Автор: Пользователь скрыл имя, 14 Мая 2013 в 16:19, курсовая работа
С ростом использования электроники и компьютеров, растет потребность в быстрой и надежной передаче информации по радио- и телефонным каналам связи, а также от одного устройства к другому. В любом канале связи присутствуют шумы – сигналы, которые могут искажать передаваемую по каналу информацию. С этими искажениями можно бороться, преобразуя передаваемую информацию при помощи кода, который будет обнаруживать, и исправлять ошибки. Так, например, в CD и DVD, в модемах, используются коды исправляющие ошибки.
ВВЕДЕНИЕ 3
1. Постановка задачи 4
2. Реализация кодов 5
2.1. Общие сведения 5
2.2. БЧХ(5, 15, 7) 5
2.3. Код Рида-Маллера 5
3. Magic Coder 7
3.1. Руководство пользователя 7
3.1.1. Меню «Файл» 7
3.1.2. Меню «Код» 7
3.2. Добавление новых кодов 8
3.3. Описание модулей программы 9
3.3.1. Модуль «BitsUtils.pas» 9
3.3.2. Модуль «MathUtils.pas» 12
3.3.3. Модуль «Code.pas» 12
3.3.4. Модуль «CodeThreads.pas» 20
3.3.5. Модуль «RM.pas» 25
3.3.6. Модуль «BCH.pas» 27
3.3.7. Прочие модули 29
4. Заключение 30
5. Литература 31
public
{ Скалярное умножение двух слов }
function ScalarMul(Word: TBits): Integer;
{ Слово Self и Word рассматриваются как векторы }
{ Вес слова }
function Weight: Integer;
end;
{ Класс TCodeWord
Кодовое слово }
TCodeWord = TWord;
{ Forward declaration }
TCode = class;
{ Класс TInBuf
Буфер ввода. Используется для чтения бит из потока }
TInBuf = class(TObject)
private
FInStream: TStream;
FBuf: TBits;
FBufRest: Integer;
{ число оставшихся (с конца) значащих бит в буфере }
public
constructor Create(InStream: TStream;
UnitsCount: Cardinal = 4096);
{ InStream - поток, из которого будет производится чтение
UnitsCount - число элементов TUnit во входном буфере }
destructor Destroy; override;
procedure Read(Word: TWord);
{ Читает следующие Word.BitsCount бит из входного потока
Если во входном потоке осталось меньше бит чем
BitsCount, то оставшиеся биты приравниваются 0 }
function EoS: Boolean;
{ Возвращает истину, если входной поток закончился }
property InStream: TStream read FInStream;
end; { TInBuf }
{ Класс TOutBuf
Используется для записи бит в поток }
TOutBuf = class(TObject)
private
FOutStream: TStream;
FBuf: TBits;
FBufRest: Integer;
{ число оставшихся значащих бит в буфере }
public
constructor Create(OutStream: TStream;
UnitsCount: Cardinal = 4096);
{ OutStream - поток, в который будет производится запись
UnitsCount - число элементов TUnit в буфере }
destructor Destroy; override;
{ Уничтожает объект, предварительно вызвав Flush }
procedure Write(Word: TWord);
{ Записывает биты слова Word в буфер, вытесняя из него
имеющиеся данные в поток вывода }
procedure Flush;
{ Сбрасывает оставшуюся информацию из буфера в поток }
property OutStream: TStream read FOutStream;
end; { TOutBuf }
{ TCode
Базовый класс для кодов }
TCode = class(TComponent)
protected
FD: Integer;
{ Это поле хранит минимальное расстояние кода. Оно
вычисляется методом GetD }
function GetD: Integer; virtual;
{ Вычисляет минимальное расстояние кода перебором.
В наследниках рекомендуется перекрыть этот метод. }
function GetDescription: String; virtual;
{ Описание кода.
Возвращает пустую строку. Наследники могут перекрыть
этот метод }
function GetK: Integer; virtual; abstract;
{ Возвращает размер информационного слова.
Наследники должны перекрыть этот метод }
function GetN: Integer; virtual; abstract;
{ Возвращает размер кодового слова.
Наследники должны перекрыть этот метод }
function GetFullName: String; virtual;
{ Возвращает полное название кода, например,
Код Рида-Маллера(2, 5).
Наследники могут перекрыть этот метод. По умолчанию
Он возвращает результат GetName }
class function GetName: String; virtual;
{ Возвращает название кода.
Наследники должны перекрыть этот метод }
public
procedure Encode(Word: TWord; CodeWord: TCodeWord); virtual;
abstract;
{ Преобразует информационное слово в кодовое
Word - информационное слово. Размер информационного
слова должен
быть не меньше чем K. При кодировании
используются лишь первые K бит
информационного слова
CodeWord - кодовое слово. Размер должен быть не
меньше чем N
Наследники должны перекрыть этот метод }
procedure Decode(RecievedWord: TCodeWord; Word: TWord);
virtual; abstract;
{ Декодирование
RecievedWord - полученное слово, которое будет
декодировано. Размер должен быть
не меньше N. Используются лишь
первые N бит слова
Word - декодированное слово. Размер должен
быть не меньше K
Наследники должны перекрыть этот метод }
{ Свойства }
property Description: String read GetDescription;
property FullName: String read GetFullName;
property Name: String read GetName;
property D: Integer read GetD;
property K: Integer read GetK;
property N: Integer read GetN;
end; { TCode }
{ Тип класса для потоковой системы }
TPersistentCode = class of TCode;
{ TCodeListViewer
Класс для просмотра зарегистрированных в потоковой системе
кодов. Является прослойкой между приложением и классом
TCodeList, который находится в части
реализации модуля (implementation) и, следовательно, не виден
вне этого модуля. Это сделано для повышения надежности
системы в целом, т.к. TCodeList играет огромную роль в ее
работе }
TCodeListViewer = class(TObject)
private
function GetCount: Integer;
{ Возвращает число кодов зарегистрированных в потоковой
системе }
function GetCodeClassName(Index: Integer): String;
{ Возвращает имя класса кода по индексу. Например,
класс кода Рида-Маллера имеет имя TRMCode }
function GetCodeName(Index: Integer): String;
{ Возвращает название кода по индексу. Т.е. результат
вызова метода GetName для соответствующего кода. }
function GetIndexOfCodeName(CodeName: String): Integer;
{ Возвращает индекс первого найденного кода название
которого совпало с заданным. Если совпадений не найдено,
то возвращается -1 }
function
GetIndexOfCodeClassName(
String): Integer;
{ Возвращает индекс первого найденного кода, имя класса
которого совпало с заданным. Если совпадений не
найдено, то возвращается -1 }
public
{ Свойства }
property Count: Integer read GetCount;
property CodeNames[Index: Integer]: String read GetCodeName;
property CodeClassNames[Index: Integer]: String read
GetCodeClassName;
property IndexOfCodeName[CodeName: String]: Integer read
GetIndexOfCodeName;
property
IndexOfCodeClassName[
Integer read GetIndexOfCodeClassName;
end;
{ Функции общего назначения }
{ Вес слова (количество ненулевых бит) }
function WordWeight(const Word; Len: Integer): Integer;
{ Регистрация кода в потоковой системе.
Незарегистрированный код не может быть использован при
декодировании из потока }
procedure RegisterCode(C: TPersistentCode);
{ Удаление кода из потоковой системы }
procedure UnRegisterCode(C: TPersistentCode);
{ Проверка параметров при кодировании и декодировании }
procedure CheckEncoderParams(InStream, OutStream:
TStream; Code: TCode);
procedure CheckDecoderParams(InStream, OutStream:
TStream; Code: TCode = TCode($1));
{ Кодирование и декодирование потоков
При кодировании в выходной поток записывается
заголовок следующего содержания:
Версия - версия кодового потока
Размер входного потока в байтах
Информация о коде (сериализованный TCode)
Далее, до конца потока, следуют упакованные
кодовые слова
При декодировании, сначала анализируется заголовок.
Если в нем указана неизвестная версия то, генерируется
Исключение EDecoder. Затем происходит попытка создать
код, используя записанную в потоке информацию о нем. После
чего, начинается само декодирование }
procedure DecodeStream(InStream, OutStream: TStream);
procedure EncodeStream(InStream, OutStream: TStream;
Code: TCode);
{ Кодирование и декодирование файлов
Эти процедуры являются надстройками над DecodeStream и
EncodeStream }
procedure DecodeFile(InputFileName, OutputFileName: String);
procedure EncodeFile(InputFileName, OutputFileName: String; Code: TCode);
{ Кодирование и декодирование без заголовка
При кодировании в поток не записывается дополнительная
информация (заголовок).
Поэтому при декодировании нужно явно указывать код,
которым нужно его производить }
procedure RawDecodeStream(InStream, OutStream: TStream;
Code: TCode);
procedure RawEncodeStream(InStream, OutStream: TStream;
Code: TCode);
{ Запись заголовка в поток }
procedure WriteHeader(InStream, OutStream: TStream;
Code: TCode);
implementation
type
{ TCodeList
Этот класс хранит информацию о кодах зарегистрированных в
Потоковой системе системе }
TCodeList = class(TObject)
private
FCodeList: TClassList;
{ Список классов }
function GetCount: Integer;
{ Число элементов в списке классов }
function GetCodeClassName(Index: Integer): String;
{ Имя класса кода по индексу, например TRMCode }
function GetCodeName(Index: Integer): String;
{ Название кода по индексу, например Код Рида-Маллера }
public
constructor Create;
destructor Destroy; override;
function Add(Code: TPersistentCode): Integer;
{ Добавляет класс в список, если его там нет,
и возвращает его индекс.
Если класс уже есть, то просто возвращается его индекс }
procedure Delete(Code: TPersistentCode);
{ Удаляет класс из списка }
{ Свойства }
property Count: Integer read GetCount;
property CodeClassNames[Index: Integer]: String read
GetCodeClassName;
property CodeNames[Index: Integer]: String read GetCodeName;
end; { TCodeList }
var
CodeList: TCodeList;
{ Экземпляр класса TCodeList. Создается в секции
инициализации данного модуля. Уничтожается в секции
финализации }
Модуль содержит классы, реализующие кодирование и декодирование в отдельном потоке (thread). Эти классы используются тестовой программой для того, чтобы визуализировать результаты работы в реальном времени, а также для предоставления возможности пользователю отменить операции кодирования и декодирования.
unit CodeThreads;
interface
uses
SysUtils, Code, Forms, Classes, Windows;
const
DEF_ONPROGRESS_INTERVAL = 500;
{ интервал в миллисекундах между событиями OnProgress. Потоки (thread)
генерируют события OnProgress для того чтобы основная программа
смогла показать пользователю текущее состояние работы потока }
type
TProgressEvent = procedure(Sender: TObject;
BitsProcessed: Int64) of object;
{ Описание обработчика события OnProgress.
Sender – объект, который сгенерировал событие OnProgress
BitsProcessed - число обработанных бит }
TDecodeCodeCreateEvent = procedure(Sender: TObject;
ACode: TCode) of object;
{ Описание обработчика события OnDecodeCodeCreate.
Данное событие генерируется после того, как поток (thread) создаст
код при декодировании. Это позволяет программе получить сведения о
коде, которым были кодированы исходные данные }
{ TCustomCodecThread
Класс для кодирования и декодирования потоков с возможностью
обработки прогресса и отмены операции }
TCustomCodecThread = class(TThread)
private
FCode: TCode;
{ код, которым производится кодирование }
FDecodeCode: TCode;
{ код использующийся для декодирования, создается автоматически на
основе информации во входном потоке }
FOutStream: TStream;
{ поток вывода}
FInStream: TStream;
{ поток ввода}
FWorking: Boolean;
{ Признак того, что поток (thread) в данный момент работает }
FInterval: Cardinal;
{ Интервал в миллисекундах, через который генерируются события
OnProgress }
FBitsProcessed: Int64;
{ Число обработанных бит (при кодировании и декодировании) }
FException: Exception;
{ Хранит объект исключительной ситуации на время работы
обработчика события OnException }
FEncodeMode: Boolean;
{ Задает режим работы потока (thread).
Если истина, то кодирование. Если ложь - декодирование }
FOnException: TExceptionEvent;
{ Указатель на обработчик события OnException.
Данное событие генерируется при возникновении исключительной
ситуации во время процесса кодирования и декодирования }
FOnProgress: TProgressEvent;
{ Указатель на обработчик события OnProgress.
Событие периодически генерируется во время процессов
кодирования и декодирования }
FOnDecodeCodeCreate: TDecodeCodeCreateEvent;
{ Указатель на обработчик события OnDecodeCodeCreate }
{ Set методы для свойств класса. Большинство из
них игнорируют новые значения для свойств класса
если FWorking = True }
procedure SetCode(const Value: TCode);
procedure SetInterval(const Value: Cardinal);
procedure SetInStream(const Value: TStream);
procedure SetOutStream(const Value: TStream);
procedure SetEncodeMode(const Value: Boolean);
{ Методы вызова обработчиков событий }
procedure CallOnDecodeCodeCreate;
procedure CallOnProgress;
procedure ExceptionHandler;
protected
{ Проверка параметров перед началом кодирования
В случае обнаружения ошибки - исключение }
procedure EncodeCheck; virtual;
{ Проверка параметров перед декодированием
В случае ошибки - исключение }
procedure DecodeCheck; virtual;
{ Запись заголовочных данных (THeader и информация о коде) в
выходной поток }
procedure WriteHeaders; virtual;
{ Чтение заголовочных данных из входного потока }
procedure ReadHeaders; virtual;
{ Кодирование входного потока и его запись в выходной поток.
Наследники могут перекрывать этот метод, если хотят изменить
процесс кодирования }
procedure EncodeProc; virtual;
{ Декодирование входного потока и его запись в выходной поток.
Наследники могут перекрывать этот метод, если хотят изменить
процесс декодирования }
procedure DecodeProc; virtual;
{ Свойства класса }
property Code: TCode read FCode write SetCode;
property DecodeCode: TCode read FDecodeCode;
{ Код использующийся при декодировании.
DecodeCode <> nil только во время процесса декодирования.
После окончания декодирования снова становится равным nil }
property EncodeMode: Boolean read FEncodeMode write SetEncodeMode;
property InStream: TStream read FInStream write SetInStream;
property OutStream: TStream read FOutStream write SetOutStream;
property Working: Boolean read FWorking;
{ События }
property OnDecodeCodeCreate: TDecodeCodeCreateEvent
read FOnDecodeCodeCreate write FOnDecodeCodeCreate;
property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
property Interval: Cardinal read FInterval write SetInterval;
property OnException: TExceptionEvent read FOnException
write FOnException;
public
constructor Create(AEncodeMode: Boolean = True);
procedure Execute; override;