Курсовая на тему Кодирование методом Файра
Работа добавлена на сайт bukvasha.net: 2015-06-30Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Введение
Деятельность людей связана с переработкой и использованием материалов, энергии и информации. Соответственно развивались научные технические дисциплины, отражающие вопросы технологии, энергетики и информатики. Информационная техника является сравнительно новой отраслью, получающей наибольшее развитие на этапе разработки и применения электронных вычислительных машин (ЭВМ) и автоматизированных систем управления (АСУ).
Информационная наука теперь находит применение в самых разнообразных областях теории и практики. Центральной ветвью является теория связи, созданная Шенноном на основе теории вероятностей.
С передачей и обработкой информации связаны действия любого автоматического устройства, поведение живого существа, творческая деятельность человека, развитие науки и техники, экономические и социальные преобразования в обществе и сама жизнь. Для более эффективного использования информации необходимо обмениваться информацией, что невозможно без её передачи по каналам связи.
При передаче информации по каналам связи может происходить искажение передаваемой информации. Для предотвращения потерь полезной информации существуют различные методы защиты. Одним из них является кодирование информации при помощи помехозащищённых кодов.
Двоичный код на все комбинации не является помехозащищённым, так как его комбинации отличаются друг от друга лишь в одном разряде, что не позволяет на приёмной стороне обнаружить и исправить возникшие ошибки. В этой связи возникает необходимость построения помехозащищённого кода.
Помехозащищённые коды – это коды, которые позволяют обнаруживать и исправлять ошибки, то есть корректировать полученные сообщения. Для достижения помехозащищенности можно ввести избыточность добавлением дополнительных контрольных разрядов.
Существует много различных алгоритмов построения помехозащищённых кодов. В данной работе рассматривается код Файра. Он является частным случаем группы циклических кодов. А именно, он относится к циклическим кодам, обнаруживающим и исправляющим пакеты ошибок.
Циклические коды являются основным классом групповых помехоустойчивых кодов и используются для исправления и обнаружения ошибок, возникающих при передаче информации по каналу связи. Устройства, обнаруживающие и исправляющие ошибки, построенные на основе циклического кода, часто применяются в различных информационных системах.
1. Постановка задачи
1.1 Анализ технического задания
В соответствии с техническим заданием требуется построить математическую модель кода Файра, для количества передаваемых сообщений 128 и для корректирующей способности bs=2 (количество исправляемых ошибок) и br = 3 (количество обнаруживаемых ошибок). Найти образующую матрицу кода.
Реализовать технические средства для его кодирования на уровне принципиальной схемы.
В записке содержатся следующие приложения
Документированный текст программы;
Принципиальная схема кодера;
Список элементов;
Техническое задание.
1.2 Теоретическое введение
1.2.1 Общие понятия и определения
По условию задачи необходимо программно осуществить схему кодирования заданной кодовой. Также требуется привести техническую реализацию схему кодера в соответствии с заданием на курсовую работу.
Коды Файра – это коды, обнаруживающие и исправляющие пакеты ошибок. Под пакетом ошибок длиной b понимают такой вид комбинации помехи, в которой между крайними разрядами, пораженными помехами, содержится b-2 разряда. Например, при b=5 комбинации помехи, т.е. пакет ошибок, могут иметь следующий вид: 10001 (поражены только два крайних символа), 11111 (поражены все символы), 10111, 11101, 11011 (не поражен лишь один символ), 10011, 11001, 10101 (поражены три символа). При любом варианте непременным условием пакета данной длины является поражение крайних символов.
Коды Файра могут исправлять пакет ошибок длиной bs и обнаруживать пакет ошибок длиной br. В кодах Файра понятие кодового расстояния d не используется.
Для кодов Файра, как и для всех циклических кодов вводятся понятия приводимых и неприводимых многочленов, а также образующих многочленов.
Многочлен (полином), который можно представить в виде произведения многочленов низших степеней, называют приводимым (в данном поле), в противном случае – неприводимым. Неприводимые многочлены играют роль, сходную с простыми числами в теории чисел. Неприводимые многочлены P(X) можно записать в виде десятичных или двоичных чисел (10011), либо в виде алгебраического многочлена. Многочлен в поле двоичных чисел называется неприводимым, если он делится без остатка только на себя и на единицу. В основу циклических кодов положено использование неприводимого многочлена P(X), который применительно к циклическим кодам называется образующим.
Образующий многочлен кода Файра Р(Х)ф определяется из выражения:
Р(Х)ф = Р(Х) (Хc+1) (1.1)
где Р(Х) – неприводимый многочлен степени l.
Из принципа построения кода следует, что
l ≥ bs, (1.2)
c ≥ bs +br-1. (1.3)
При этом с не должно делиться нацело на число е:
е=2l-1. (1.4)
Неприводимый многочлен Р(Х) выбирают из таблицы 1.1 согласно уравнению (1.2), но так, чтобы удовлетворялось условие (1.4). Длина слова n равна наименьшему общему кратному чисел с и е, так как только в этом случае многочлен Хn+1 делится на Р(Х)ф без остатка:
n=НОК (е, с). (1.6)
Число контрольных символов:
m=c+l. (1.5)
Таблица 1.1. Неприводимые многочлены и их эквиваленты
Р(Х1)=Х+1→3→11 | Р(Х5)= Х5+Х3+Х2+Х+1→47→101111 |
Р(Х2)=Х2+Х+1→7→111 | Р(Х5)= Х5+Х4+Х2+Х+1→55→110111 |
Р(Х3)=Х3+Х+1→11→1011 | Р(Х5)= Х5+Х4+Х3+Х+1→59→111011 |
Р(Х3)= Х3+Х2+ 1→13→1101 | Р(Х5)= Х5+Х4+Х3+Х2+1→61→111101 |
Р(Х4)=Х4+Х+1→19→10011 | Р(Х6)= Х6+Х+1→67→1000011 |
Р(Х4)=Х4+Х3+1→25→11001 | Р(Х7)= Х7+Х3+1→137→10001001 |
Р(Х4)= Х4+Х3+ Х2+Х+1→31→11111 | Р(Х8)= Х8+Х4+Х3+ Х2+1→285→100011101 |
Р(Х5)= Х5+Х2+1→37→100101 | Р(Х9)= Х9+Х4+1→1041→1000010001 |
Р(Х5)= Х5+Х3+1→41→101001 | Р(Х10)= Х10+Х3+ 1→2057→10000001001 |
Коды Файра являются помехоустойчивыми кодами и используются для исправления и обнаружения ошибок, возникающих при передаче информации по каналу связи. Способность кода обнаруживать и исправлять ошибки обусловлена наличием в кодовом слове помимо информационных разрядов избыточных (проверочных) символов, значения которых вычисляются при кодировании по определенным алгоритмам. Проверка значений этих символов на приемной стороне, также выполняемая по определенным алгоритмам, позволяет обнаруживать и исправлять ошибки.
В кодах Файра каждая комбинация кодируется самостоятельно (в виде блока) таким образом, что информационные k и контрольные m символы всегда находятся на определенных местах:
10101010 10010
k m
n=m+k.
Причем следует помнить, что в данном случае мы используем в качестве символов – биты информации. Т.е. один символ – может быть представлен двумя способами: либо «1», либо «0».
В общем случае, если заданную кодовую комбинацию Q(X) умножить на образующий многочлен P(X), получится, обладающий теми или иными корректирующими свойствами в зависимости от выбора P(X). Однако в этом коде контрольные символы m будут располагается в самых разнообразных местах кодовой комбинации. Такой код не является систематическим, что затрудняет его схемную реализацию. Ситуацию можно упростить, если контрольные символы приписать в конец кода.
Групповые коды с такой структурой принято обозначать (n, k) кодами, отражая таким образом в названии кода общую длину кодового слова и количество информационных символов, на передачу которых рассчитан код.
При описании циклических кодов n разрядные кодовые комбинации представляются в виде многочленов фиктивной переменной Х. Показатели у переменной Х соответствуют номерам разрядов (начиная с нулевого), а коэффициентами при Х для двоичных кодов будут 0 и 1. Например, кодовая комбинация 1011 в виде многочлена запишется следующим образом:
Члены с нулевыми коэффициентами при записи многочлена опускаются, и окончательно получим:
Наибольшая степень Х в слагаемом с ненулевым коэффициентом называется степенью многочлена. Все действия над кодовыми комбинациями сводятся действиям над многочленами [2, 3].
Способность кодов Файра обнаруживать и исправлять ошибки связана с тем, что разрешенные кодовые комбинации будут делиться на g(x) без остатка, а запрещенные кодовые комбинации будут давать остатки, по виду которых можно обнаружить и исправить ошибку.
Итак, исходя из вышеописанного, можно дать такую математическую модель решаемой задачи.
1.2.2 Общая математическая модель и оптимальные методы решения поставленной задачи
По условию задачи для декодирования переданных кодовых последовательностей необходимо воспользоваться кодами Файра. Это такие коды, которые могут обнаруживать и исправлять пакеты ошибок. Для того, чтобы представить код заданного числа разрядов в виде кодов Файра, необходимо провести ряд вычислений. Требуется найти остаток, удовлетворяющий ряду требований. Эти требования можно выразить в виде неравенств и уравнений (1.1) – (1.5). Это и будет математическая модель для задания на курсовую работу.
Этот код является одним из наиболее эффективных циклических кодов. Возможность обнаружения и исправления практически любых ошибок при относительно малой избыточности по сравнению с другими кодами, а также простота технической реализации аппаратуры кодирования и декодирования делает эти коды широко распространенными. В кодировании избыточность определяется отношением контрольных символов m к длине слова:
И = m/n,
где n=m+k [2].
Так, для кода Файра (120, 108) с исправляющей способностью bs=4 избыточность будет составлять: И=12/120=0,1.
С другой стороны, для одной из разновидности циклических кодов – кодов БЧХ (127, 99) (взято близкое значение n к рассмотренному ранее коду Файра) с такой же исправляющей способностью исправляющая способность будет равна: И=28/127=0,22, т.е. значительно выше, чем у кода Файра.
Это очевидно: исправить четыре ошибки, находящиеся в одном месте, проще, чем ошибки, рассредоточенные по всей длине комбинации [2].
1.2.3 Пример построения кодов Файра
Рассмотрим на примере.
Пусть требуется построить код Файра для bs=4, br=5.
Исправить пакет bs=4 – значит исправить одну из следующих комбинаций ошибок, пораженных помехами: 1111, 1101, 1011 и 1001. В тоже время этот код может обнаружить одну из комбинаций в пять символов, рассмотренных ранее: 10001, 11111 и т.д.
На основании (1.2) и (1.3) c≥8 и l≥4. По таблице 1.1 находим неприводимый многочлен четвертой степени: Р(Х)=Х4+Х+1.
Согласно (1.4), е=24-1=15. Поэтому длина кода n=15*8=120. Из (1.5) число контрольных символов m=8+4=12, то есть в данном случае оно равно степени образующего многочлена. В итоге получаем код (120, 108). Избыточность такого кода, если учитывать его исправляющую способность, невелика: И=12/120=0,1.
Проверочные символы получаются при делении исходного кода с приписанными m нулями на образующий многочлен кода Файра. Это можно выразить в виде формулы:
Таким образом, остаток от деления R(x) и будет образовывать проверочные символы. Приписывание m нулей соответствует умножению на хm. Итак, мы получаем код:
F(x) = G(x) · xm + R(x)
1.2.4 Матричная запись кода
Полная образующая матрица циклического кода составляется из двух матриц: единичной (соответствующей k информационным разрядам) и дополнительной матрицы (соответствующей проверочным разрядам) [2]. По образующей матрице можно рассчитывать все кодовые комбинации.
Нахождение элементов дополнительной матрицы.
Дополнительную матрицу находят путем деления единицы с нулями на выбранный многочлен Р(Х) и выписывания всех промежуточных остатков. При этом должны быть соблюдены следующие условия:
а) число остатков должно быть равно числу информационных символов k;
б) для дополнительной матрицы пригодны лишь остатки с весом W, не меньшим числа обнаруженных ошибок r, т.е. в данном случае не меньшим 3 (W≥3); так как обнаруживается не менее трех ошибок.
Из условий а) и б) определяется количество нулей, приписываемых к единице при делении ее на многочлен Р(Х);
в) так как элементы дополнительной матрицы являются для данной комбинации контрольными символами, то число разрядов дополнительной матрицы равно числу контрольных символов m. Вследствие того, что степень образующего многочлена выбирают равной m, число разрядов дополнительной матрицы равно также степени образующего многочлена. Разрядность остатка равна степени образующего многочлена.
Составление образующей матрицы.
Берут транспонированную единичную матрицу и справа приписывают к ней элементы дополнительной матрицы.
Нахождение всех комбинаций циклического кода. Это достигается суммированием по модулю 2 всевозможных сочетаний строк образующей матрицы.
1.3 Математическая модель
Исходя из технического задания, bs=2, br=3, то есть код способен обнаруживать три ошибки, а исправлять только две. Таким образом вышеприведенные формулы
Р(Х)ф = Р(Х) (Хs+1)
где Р(Х) – неприводимый многочлен степени l.
l ≥ bs,
c ≥ bs +br-1.
При этом с не должно делиться нацело на число е:
е=2l-1.
Эти уравнения и будут являться математической моделью решаемой задачи. Применительно к данным технического задания:
l ≥ 2 (возьмем l=2).
с ≥ 2+3–1≥4 (возьмем c=5).
e=22-1=3 (5 не делится нацело на 3).
Р(Х)ф = Р(Х2) (Х5+1).
Возьмем Р(Х2) = х2+x+1, тогда
На основании формулы (1.6) общее число символов n равно: n=НОК (3, 5)=15. Причем l, c, e были вычислены на основании формул (см выше). Таким образом, l=2, c=5, e=3. Итак, из (1.5) следует, что число проверочных символов: m=2+5=7. То есть число информационных символов: n=15–7=8, Что как раз нам подходит для передачи 128 сообщений, учитывая, что нулевое состояние выбрасывается из рассмотрения. Итак, имеем код (15,8). При этом должно выполняться, что c/e не делится нацело. Выберем образующий многочлен для конкретно заданного кода Файра. Исходя из условия построенной математической модели:
При выборе образующего многочлена необходимо руководстсвоваться правилами: степень образующего многочлена не может быть меньше числа контрольных символов (лучше, если l=m); если неприводимых многочленов такой степени несколько, то выбирают самый короткий. Именно исходя из этих правил, для данной работы был выбран в качестве образующего многочлен Pф(X)=11100111. Итак, для получения m проверочных символов необходимо произвести деление исходного слова на образующий многочлен кода Файра. При этом частичное суммирование при делении должно производиться по модулю 2.
1.4 Построение образующей матрицы
Из выше полученных расчетов мы знаем, что число информационных символов (бит) равно 8. Следовательно размерность единичной матрицы будет 8. Число проверочных символов = 7, следовательно получим дополнительную матрицу, имеющую 8 строк и 7 столбцов.
Найдем дополнительную матрицу:
100000000000000|11100111
11100111 |–
–
011001110 1-й остаток
11100111
–
010000110 4-й остаток
11100111
–
011000010 5-й остаток
11100111
–
001001010 6-й остаток
10010100 7-й остаток
11100111
–
01110011 8-й остаток
Итак, дополнительная матрица имеет вид:
m1 | m2 | m3 | m4 | m5 | m6 | m7 |
1 | 1 | 0 | 0 | 1 | 1 | 1 |
0 | 1 | 0 | 1 | 0 | 0 | 1 |
1 | 0 | 0 | 0 | 0 | 1 | 1 |
1 | 0 | 0 | 0 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 0 | 0 | 1 |
0 | 1 | 0 | 0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 | 1 | 0 |
1 | 1 | 1 | 0 | 0 | 1 | 1 |
Составим образующую матрицу:
k1 | k2 | k3 | k4 | k5 | k6
| k7 | k8 | m1 | m2 | m3 | m4 | m5 | m6 | m7 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
1 | 1 | 1 | ||||||||||||
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
Нахождение всех комбинаций циклического достигается суммированием по модулю 2 всевозможных сочетаний строк образующей матрицы.
В данной главе была освещена теоретические основы для решения задачи курсовой работы. Были описаны структура и специфика кодов Файра и методы кодирования. Таким образом, была подведена база для последующей реализации поставленной задачи на языке программирования.
2. Техническая реализация кодера
2.1 Модульная структура кодера и его работа
Основу кодирующих устройств двоичных циклических кодов составляют регистры сдвига с обратными связями, позволяющие осуществлять как умножение, так и деление многочленов с приведением коэффициентов по модулю 2. Такие регистры также называют многотактными линейными переключательными схемами и линейными кодовыми фильтрами Хаффмена. Они состоят из ячеек памяти, сумматоров по модулю 2 и устройств умножения на коэффициенты многочленов множителя или делителя. В случае двоичных кодов для умножения на коэффициент, равный 1, требуется только наличие связи в схеме. Если коэффициент равен 0, то связь отсутствует. Сдвиг информации в регистре осуществляется импульсами, поступающими с генератора продвигающих импульсов. На вход устройств поступают только коэффициенты многочленов, причем начиная с коэффициента при переменной в старшей степени.
Как указывалось выше, образование циклического кода (в данном случае кода Файра) состоит из двух операций: умножения комбинации обычного двоичного кода G(X) на одночлен Xm и последующего деления этого произведения на выбранный образующий многочлен P(X). Полученные в остатке от деления контрольные символы приписываются к кодируемой комбинации. Таким образом, кодирующее устройство должно совмещать функции умножения и деления.
Рассмотрим методику построения кодирующего устройства. Пусть требуется составить схему кодирующего устройства для многочлена
P(X)=X5+X2+X+1.
Схематичное изображение кодирующего устройства можно увидеть на рисунке 2.1.
Рис. 2.1. Схематичное изображение кодирующего устройства
Схема, изображенная на рис. 2.1, работает следующим образом. В исходном состоянии ключ К1 находится в положении 1, а ключ К2 замкнут. Все подлежащие кодированию информационные символы, начиная со старшего разряда, поступают одновременно на выход и через сумматор на входе в схему кодирования. После того как пройдет последний символ k, ключ К1 переключится в положение 2, а ключ К2 размыкается. После этого регистр делает m шагов, равных числу ячеек, т.е. восемь шагов. И весь остаток поступает на выход. Этот остаток представляет собой контрольные символы, следующие за информационными символами.
Принципиальная схема данного кодирующего устройства представлена в приложениях.
Аппаратная реализация ключей была опущена и заменена схемотехническим упрощенным изображением SA1 и SA2. В схеме эти ключи должны срабатывать в той же последовательности, как и на рис 1.3.
Поясним назначение выводов разъема:
XT1: Внешний ГТИ (генератор тактовых импульсов).
XT2: Вход кодирующего устройства. Подача входных импульсов.
XT3: Выход кодирующего устройства.
XT4: +5 Вольт
XT5: общий. (0 Вольт)
Перечень элементов, используемый в кодере – представлен также в приложении и таблице 2.1.
2.2 Выбор микросхем для реализации принципиальной схемы кодера
Таблица 2.1. Перечень элементов схемы
Поз. обозн. | Наименование | Количество |
DD1, DD2 | КР531ТМ8 | 2 |
DD3, DD4 | КР1554ЛП5 | 2 |
Для реализации схемы памяти используются микросхемы серии КР531ТМ8, которые содержат по четыре D – триггера, имеющих общую цепь питания. У каждого триггера есть выходы Q и Q. Для реализации функции сложения по модулю 2 используются микросхемы серии КР1554ЛП5. Они содержат по четыре логических элемента исключающее ИЛИ.
В данной главе представлено описание работы кодирующего устройства, функциональное изображение схемы кодирующего устройства. Приведено ее описание, а также представлен набор микросхем, используемых для реализации принципиальной схемы кодера.
3. Описание программных средств, разработанных в ходе реализации проекта
3.1 Структура системы
Для решения задачи предлагается объектно-ориентированный подход. Это наиболее перспективный подход к реализации любой задачи. Кроме того, язык MSVС++ 6.0 – это полностью объектно-ориентированный язык, включающий в себя удобные средства реализации этого подхода.
Объектно-ориентированный подход имеет преимущества перед другими методами, прежде всего, из-за его наглядности, структурированности: методы и переменные, логически связанные между собой, объединены в классы. Сообщение между различными классами доступно через имена этих классов.
В целом объектно-ориентированный подход получил широкое распространение из-за поддержки наследования, инкапсуляции и полиморфизма. Производные классы от классов-прародителей могут наследовать их методы, поэтому нового переопределение старых методов не требуется. Классы могут содержать как методы, так и функции, что максимально удобно при объединении логически связанных данных. Один класс может иметь множество производных классов, что очень удобно с точки зрения экономии времени, поскольку большинство процедур заново переопределять не приходится.
Поэтому выбор этого подхода наиболее оправдан, перспективен и удобен для дальнейшего расширения разработки.
Возможности MSVС++ 6.0 по решению задач, предполагающих работу с информацией разнообразны, поскольку на этом языке программирования можно реализовать практически любой алгоритм. Поставленную задачу можно решить, используя алгоритмы сложения по модулю 2. В языке С есть средство для решения второй проблемы. Сложение по модулю два осуществляется при использовании оператора ^. Он является эквивалентом оператора mod в языке программирования Pascal и реализует сложение по модулю два справа и слева стоящих от него операндов. Общая структура этой команды:
(Результат) = (Операнд1) ^ (Операнд2)
Результат сложения можно представить в виде таблицы
Таблица 3.1. Сложение по модулю два
Операнд 1 | Операнд 2 | Результат |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Для конкретной реализации в программе должны содержаться массивы для хранения требуемых для работы алгоритма переменных: CODE – массив разрядов, входящих в сообщение, должен вводиться пользователем (9 разрядов – информационные). И массив G_CODE для закодированного сообщения (9 разрядов – информационные, 5 разрядов – проверочные).
Проект также должен содержать справку об авторе, о назначении данной программы, а также о том, как с ней работать.
3.2 Входные данные, форма представления результатов
Входными данными программы является код, который пользователь должен ввести нажатием мыши на соответствующие поля (в программе это реализовано интуитивно понятными ChackBox-ами, т.е. галочками в квадратных полях. Поставленная галочка – означает 1 в информационных битах.). Эти поля пронумерованы в соответствие привычному нам расположению бит входного сообщения. Результаты представлены в виде итогового закодированного сообщения при помощи кодов Файра. Результат содержит строку из 8-ми информационных и 7-ми проверочных символов.
3.3 Спецификация на программу в целом
Программа выполняет следующие функции:
1). Кодирование заданной битовой последовательности с помощью кодов Файра;
2) Схематично представляет две матрицы – дополнительную и единичную.
3) Выводит динамически результат колирования, т.е. достаточно только изменить входное сообщение и результат тут же просчитывается и выводится на экран.
Итак, входные данные:
BOOL information[8] – массив, куда заносятся биты сообщения, которые необходимо заколировать.
BOOL m[8] [7] – массив для хранения дополнительной матрицы, заранее посчитанной для кодера. Матрица имеет 8 строк, т. к. у нас 8 информционных бит и 7 столбцов, т. к. у нас 7 проверочных символов.
Выходные данные:
BOOL pro[7] – 7 проверочных символов, которые получены в результате кодирования.
При создании программы било сделано нововведение, а именно – программа написана полностью на API. Это позволило намного сократить полученный EXE-файл. А также увеличить скорость работы программы. Такое введение было сделано с целью получения дополнительного опыта в программировании. Т.к. на API был сделан полностью интерфейс со своими особенностями, то текст программы получился обширным, содержащий большое кол-во модулей, классов, объектов, переменных. В связи с этим, с расчетном задании не была приведена спецификация на программные модули.
3.4 Системные требования
486dx2–66
16 Mb RAM
2Mb Video Ram
Screen Resolution 800*600*16bit
HDD – 1 Mb
OS Windows 98, МЕ, ХР, Windows NT 4.0 или выше.
Программа соответствует требованиям технического задания. Она успешно кодирует введенную двоичную последовательность при помощи кодов. Созданный удобный дружественный интерфейс – понятен и прост. Кроме того, комментарии позволяют быстро разобраться в программе и при необходимости внести в нее поправки.
В программе широко использовались элементы Единого Пользовательского Интерфейса (Common User Access), а также элементы технологии TOP DOWN.
Процедуры написанные для данной программы будут в дальнейшем использоваться в других программах. Написание данной программы принесло большую пользу в освоении структурного программирования и курса «Теория передачи информации».
4. Результативная часть
4.1 Тестирование
Тестирование – это процесс, посредством которого проверяется правильность программы. Его цель – показать, что программа правильно работает в соответствии с проектными спецификациями.
При тестировании проверялась работа каждого модуля в отдельности, а также всей программы в целом. Было проведено несколько тестирований, после каждого из которых проводилась доработка программы и устранение ошибок. Тестирование проводилось из расчета на то, программой могут пользоваться неопытные пользователи, которые непредсказуемы в работе с программой.
На первом этапе тестирования вводилось несколько новых данных, и с ними проводились различные операции. Результаты этого тестирования показали правильную работу модуля, обеспечивающего ввод данных (проверялась защита от некорректного ввода и запоминание данных в память),
Результаты тестирования показали устойчивую работу программы.
Тестирование показало, что программа полностью соответствует техническому заданию. Верно разработан алгоритм и реализована процедура кодирования.
При тестировании мы получили следующие примеры выполнения программы и алгоритма, что подтверждает правильность задания программы (в данном случае применялся метод черного ящика):
Приведем тестовую таблицу с введенными кодами, закодированными последовательностями, то есть покажем соответствие между входными и выходными данными.
Таблица 4.1. Тестирование программы
Введенный код | Проверочные символы | Код с проверочными символами |
10000000 | 1110011 | 100000001110011 |
01000000 | 1001010 | 010000001001010 |
11111111 | 0100010 | 111111110100010 |
11110000 | 1111101 | 111100001111101 |
00000011 | 1001110 | 000000111001110 |
00000110 | 1111011 | 000001101111011 |
10101010 | 0111100 | 101010100111100 |
4.2 Описание пользовательского интерфейса
После запуска программы на выполнение на экране появляется диалоговое окно, содержащее 4 поля:
1) Поле ввода информационных бит.
2) Поле, иллюстрирующее единичную матрицу.
3) Поле, иллюстрирующее дополнительную матрицу.
4) Поле, иллюстрирующее закодированное сообщение.
4.3 Инструкция пользователю
Для ввода информационных бит – необходимо в поле ввода проставить галочки в тех битах, которые = 1. Там, где должны быть нули, оставить пустым.
После ввода информации – программа автоматически просчитывает выходной код и выводит его в поле ответа. Дополнительные иллюстрирующие поля показывают дополнительную информацию.
В результате тестирования были обнаружены ошибки, которые впоследствии были устранены. В результате тестирования было получено, что программа является работоспособной. Программа правильно находит и строит код Файра.
Заключение
В результате проделанной работы была построена математическая модель помехозащищенного группового кода Файра (15, 8), который кодирует информацию так, что при приеме может быть обнаружена пачка ошибок длиной 3 и исправлена пачка ошибок длиной 2 (bs = 2, br = 3). Данный код кодирует передаваемое сообщение из 8 бит, количество различных сообщений – 128.
Математическая модель данного кода представляет собой программу, написанную с помощью языка MSVC++ 6.0. Программа была реализована на API, что позволило освоить новый способ реализации пользовательского интерфейса. Составленная программа работает в соответствии с техническим заданием и позволяет кодировать вводимые сообщения.
Также в курсовой работе была разработана принципиальная схема кодера, реализующего перевод двоичного кода в код Файра в соответствии с техническим заданием.
Полное описание проведенной работы с пояснительными рисунками, таблицами и различными расчетами содержатся в данной расчетно-пояснительной записке. Графическая часть записки – принципиальная схема – выполнена в соответствии с требованиями ЕСКД и вынесена в приложение. А также к расчетно-пояснительной записке прилагаются документированный текст программы, список элементов, используемых для построения принципиальной схемы, и техническое задание.
На основании вышеизложенного материала можно сделать вывод, что задача, поставленная в техническом задании, – выполнена.
Приложение
Документированный текст программы.
#include «MyWWindow.h»
#include «WContener.h»
#include «WBottom.h» // Added by ClassView
#include «WLineSeparator.h»
#include «WBox.h»
#include «WChackBox.h»
class MyMainWindow:public MyWWindow
{
public:
bool timer;
WContener MainWndMCC;
void CloseMyWindow();
virtual void DrawWindow (/*WContener mcc,*/HWND hwnd, HDC hdc);
virtual void DrawMyControls (/*WContener *mcc, HDC hdc*/HWND hwnd, HDC hdc);
virtual void OnMouseMoveMyctr (HWND hwnd, UINT uMsg, LPARAM lParam);
virtual void OnMouseLBUp (UINT msg, LPARAM lParam);
virtual void MinimizeWnd();
//WLineSeparator b;
WBottom CloseBt; // (WContener*, int, int, int, int, bool, char*, WFunc);
WBottom MinimizeBt;
WBottom File;
WLineSeparator LeftLine;
WLineSeparator UnderMenuLine;
WChackBox inf[8];
WChackBox infout[8];
BOOL information[8];
BOOL pro[7];
BOOL m[8] [7];
WBox In;
WBox Out;
WBox Matrt;
WBox Matrm;
WContener WndMCC;
MyMainWindow();
MyMainWindow(HWND);
virtual void MyMainWindow: OnBottonPress(int);
virtual ~MyMainWindow();
};
#endif //! defined (AFX_MYMAINWINDOW_H__583A9BDB_9B1A_49BB_A851_140263AA24BD__INCLUDED_)
// MyMainWindow.cpp: implementation of the MyMainWindow class.
//
//////////////////////////////////////////////////////////////////////
#include «stdafx.h»
#include «MyMainWindow.h»
#include «MyWWindow.h»
#include «WContener.h»
#include «globalsdef.h»
#include «Windowsx.h»
#include «resource.h»
#include «Wingdi.h»
#include «Windows.h»
#include «WLineSeparator.h»
#include «WBottom.h»
#include «WBox.h»
//Windows.h
// #include «gam.h»
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
MyMainWindow: MyMainWindow()
{
m[0] [0]=(BOOL) 1;
m[0] [1]=(BOOL) 1;
m[0] [2]=(BOOL) 0;
m[0] [3]=(BOOL) 0;
m[0] [4]=(BOOL) 1;
m[0] [5]=(BOOL) 1;
m[0] [6]=(BOOL) 1;
m[1] [0]=(BOOL) 0;
m[1] [1]=(BOOL) 1;
m[1] [2]=(BOOL) 0;
m[1] [3]=(BOOL) 1;
m[1] [4]=(BOOL) 0;
m[1] [5]=(BOOL) 0;
m[1] [6]=(BOOL) 1;
m[2] [0]=(BOOL) 1;
m[2] [1]=(BOOL) 0;
m[2] [2]=(BOOL) 1;
m[2] [3]=(BOOL) 0;
m[2] [4]=(BOOL) 0;
m[2] [5]=(BOOL) 1;
m[2] [6]=(BOOL) 0;
m[3] [0]=(BOOL) 1;
m[3] [1]=(BOOL) 0;
m[3] [2]=(BOOL) 0;
m[3] [3]=(BOOL) 0;
m[3] [4]=(BOOL) 0;
m[3] [5]=(BOOL) 1;
m[3] [6]=(BOOL) 1;
m[4] [0]=(BOOL) 1;
m[4] [1]=(BOOL) 1;
m[4] [2]=(BOOL) 0;
m[4] [3]=(BOOL) 0;
m[4] [4]=(BOOL) 0;
m[4] [5]=(BOOL) 0;
m[4] [6]=(BOOL) 1;
m[5] [0]=(BOOL) 0;
m[5] [1]=(BOOL) 1;
m[5] [2]=(BOOL) 0;
m[5] [3]=(BOOL) 0;
m[5] [4]=(BOOL) 1;
m[5] [5]=(BOOL) 0;
m[5] [6]=(BOOL) 1;
m[6] [0]=(BOOL) 1;
m[6] [1]=(BOOL) 0;
m[6] [2]=(BOOL) 0;
m[6] [3]=(BOOL) 1;
m[6] [4]=(BOOL) 0;
m[6] [5]=(BOOL) 1;
m[6] [6]=(BOOL) 0;
m[7] [0]=(BOOL) 1;
m[7] [1]=(BOOL) 1;
m[7] [2]=(BOOL) 1;
m[7] [3]=(BOOL) 0;
m[7] [4]=(BOOL) 0;
m[7] [5]=(BOOL) 1;
m[7] [6]=(BOOL) 1;
WndMCC. SetNomber(25);
MinimizeBt. SetBottom (&WndMCC, MAINWND_WIDTH-18*2–4*2, 1, 18,18, TRUE, «_»);
CloseBt. SetBottom (&WndMCC, MAINWND_WIDTH-18–4, 1, 18,18, TRUE, «x»);
In. SetBox (&WndMCC, 20,40,500,40, TRUE, TRUE, «Ввод информационных символов (бит):»);
In. SetBox (&WndMCC, 20,300,500,40, TRUE, TRUE, «Вывод закодированного сообщения:»);
int i=50;
inf[0].SetChackBox (&WndMCC, 40+i*0,50,10, TRUE, TRUE, «7», FALSE);
inf[1].SetChackBox (&WndMCC, 40+i*1,50,10, TRUE, TRUE, «6», FALSE);
inf[2].SetChackBox (&WndMCC, 40+i*2,50,10, TRUE, TRUE, «5», FALSE);
inf[3].SetChackBox (&WndMCC, 40+i*3,50,10, TRUE, TRUE, «4», FALSE);
inf[4].SetChackBox (&WndMCC, 40+i*4,50,10, TRUE, TRUE, «3», FALSE);
inf[5].SetChackBox (&WndMCC, 40+i*5,50,10, TRUE, TRUE, «2», FALSE);
inf[6].SetChackBox (&WndMCC, 40+i*6,50,10, TRUE, TRUE, «1», FALSE);
inf[7].SetChackBox (&WndMCC, 40+i*7,50,10, TRUE, TRUE, «0», FALSE);
for (int j=0; j<=7; j++)
{
inf[j].MARK=FALSE;
information[j]=FALSE;
}
Matrt. SetBox (&WndMCC, 20,100,230,180, TRUE, TRUE, «Единичная трансп. матр.»);
Matrt. SetBox (&WndMCC, 290,100,230,180, TRUE, TRUE, «Матрица дополнений:»);
//Box1. NomberOfBitmaps=10;
//timer=FALSE;
//inf. SetChackBox (&WndMCC, 40,320,250, TRUE, FALSE, «Do`nt ask this question agen…», TRUE);
//Box2. SetChackBox (&WndMCC, 40,340,250, TRUE, TRUE, «Enabled clock in the right khoner of the screen», TRUE);
}
MyMainWindow: MyMainWindow (HWND hwnd)
{
// void (*f)();
//f=CloseMyWindow;
myhwnd=hwnd;
//MainWndMCC(8);
// (__cdecl*) (void) qq;
// (__cdecl *) (void) qqq;
// (this->CloseMyWindow);
}
MyMainWindow:~MyMainWindow()
{
}
void MyMainWindow: DrawWindow (HWND hwnd, HDC hdc)
{
//PAINTSTRUCT ps;
// HDC hdc;
RECT crect, rect;
HBRUSH brush;
GetClientRect (hwnd, &crect);
rect = crect;
crect.top=KEWL_SZ_CAPTION_HEIGHT;
rect.bottom = KEWL_SZ_CAPTION_HEIGHT;
// !!!!!!!!!!!!!!!!???????????????
if (FALSE/*GetActiveWindow()!= hwnd*/)
{for (WORD i = 0; i <= WndMCC.count; i++){WndMCC.ctr[i].enabled=FALSE;}}
else {for(WORD i = 0; i <= WndMCC.count; i++){WndMCC.ctr[i].enabled=TRUE;}}
//hdc = BeginPaint (hwnd, &ps);
brush = CreateSolidBrush(CLRMainWindowBackGround);
TRIVERTEX vert[2];
GRADIENT_RECT gRect;
if (GetActiveWindow() == hwnd)
{
vert [0].x = 0;
vert [0].y = 0;
vert [0].Red = 0x0000;
vert [0].Green = 0x0000;
vert [0].Blue = 0xff00;
vert [0].Alpha = 0x0000;
vert [1].x = MAINWND_WIDTH;
vert [1].y = KEWL_SZ_CAPTION_HEIGHT;
vert [1].Red = 0xcc00;
vert [1].Green = 0xbb00;
vert [1].Blue = 0xee00;
vert [1].Alpha = 0x1800;
}
else
{
vert [0].x = 0;
vert [0].y = 0;
vert [0].Red = 0x4400;
vert [0].Green = 0x4400;
vert [0].Blue = 0x4400;
vert [0].Alpha = 0x0000;
vert [1].x = MAINWND_WIDTH;
vert [1].y = KEWL_SZ_CAPTION_HEIGHT;
vert [1].Red = 0xaa00;
vert [1].Green = 0xaa00;
vert [1].Blue = 0xaa00;
vert [1].Alpha = 0x1800;
}
gRect. UpperLeft = 0;
gRect. LowerRight = 1;
GradientFill (hdc, vert, 2,&gRect, 1, GRADIENT_FILL_RECT_H);
FillRect (hdc, &crect, brush);
DeleteObject(brush);
//brush = CreateSolidBrush((GetActiveWindow() == hwnd)? KEWL_CLR_CAPTION_ACTIVE:KEWL_CLR_CAPTION_INACTIVE);
//FillRect (hdc, &rect, brush);
//DeleteObject(brush);
rect.left=rect.left +2;
rect.top=rect.top +2;
SetBkMode (hdc, TRANSPARENT);
//SetTextColor (hdc, RGB (148,178,255));
SetTextColor (hdc, RGB (40,40,40));
//rect.left=rect.left +1;
//rect.top=rect.top +1;
DrawText (hdc, GAM_MAINWND_CAPTION, -1, &rect, DT_CENTER | DT_VCENTER);
rect.left=rect.left -2;
rect.top=rect.top -2;
SetTextColor (hdc, (GetActiveWindow() == hwnd)? KEWL_CLR_TITLE_ACTIVE:KEWL_CLR_TITLE_INACTIVE);
//SetBkColor (hdc, (GetActiveWindow() == hwnd)? KEWL_CLR_CAPTION_ACTIVE:KEWL_CLR_CAPTION_INACTIVE);
DrawText (hdc, GAM_MAINWND_CAPTION, -1, &rect, DT_CENTER | DT_VCENTER);
}
void MyMainWindow: DrawMyControls (/*WContener *mcc, HDC hdc*/HWND hwnd, HDC hdc)
{
int k, ii;
// транспонированная матрица
for (k = 0; k<=7; k++)
{
for (int e=0; e<=7; e++)
if (e == (7-k))
{
DrawMyText (hwnd, hdc, 15*e+70,120+k*15,10, TRUE, «1»);
}
else
{
DrawMyText (hwnd, hdc, 15*e+70,120+k*15,10, TRUE, «0»);
}
}
// Вывод дополнительной матрицы
for (k = 0; k<=7; k++)
{
for (int e=0; e<=6; e++)
if (m[k] [e] == 1)
{
DrawMyText (hwnd, hdc, 12*e+330,130+k*12,10, TRUE, «1»);
}
else if (m[k] [e] == 0)
{
DrawMyText (hwnd, hdc, 12*e+330,130+k*12,10, TRUE, «0»);
}
}
//
for (k = 0; k<=7; k++)
{
if (information[k] == TRUE)
{
DrawMyText (hwnd, hdc, 15*k+30,315,10, TRUE, «1»);
}
else if (information[k] == FALSE)
{
DrawMyText (hwnd, hdc, 15*k+30,315,10, TRUE, «0»);
}
}
for (ii=0; ii<=6; ii++) {pro[ii]=0;} // Очистка
for (ii=0; ii<=7; ii++)
{
if (information [ii]==TRUE)
{
for (k=0; k<=6; k++)
{
pro[k]=((BOOL) pro[k]) ^ ((BOOL) (m [7-ii] [k]));
}
}
;
}
for (k = 0; k<=6; k++)
{
if (pro[k] == TRUE)
{
DrawMyText (hwnd, hdc, 15*(k+11)+50,315,10, TRUE, «1»);
}
else if (pro[k] == FALSE)
{
DrawMyText (hwnd, hdc, 15*(k+11)+50,315,10, TRUE, «0»);
}
}
/*
UpdateWindow (
hwnd // handle to window
);
*/
SIZE ts;
for (WORD i = 0; i <= WndMCC.count; i++)
switch (WndMCC.ctr[i].type)
{
// ******
case MC_BUTTON:
DrawBotton (hwnd, hdc,&WndMCC.ctr[i]);
break;
case MC_LINE_SEPARATOR_VERT:
DrawLineSeparator (hwnd, hdc, WndMCC.ctr[i].x, WndMCC.ctr[i].y, WndMCC.ctr[i].UD, 2, WndMCC.ctr[i].visible, WndMCC.ctr[i].enabled, WndMCC.ctr[i].ACTIVATED, WndMCC.ctr[i].hilight, "»);
break;
case MC_LINE_SEPARATOR_HOR:
DrawLineSeparator (hwnd, hdc, WndMCC.ctr[i].x,
WndMCC.ctr[i].y, WndMCC.ctr[i].LR, 1,
WndMCC.ctr[i].visible, WndMCC.ctr[i].enabled,
WndMCC.ctr[i].ACTIVATED, WndMCC.ctr[i].hilight,
WndMCC.ctr[i].text);
//DrawLineSeparator (hwnd, hdc, 210,220,110,2, TRUE, TRUE, TRUE, TRUE, «WAV options»);
break;
case MC_BOX:
DrawBox (hwnd, hdc, WndMCC.ctr[i].x, WndMCC.ctr[i].y, WndMCC.ctr[i].LR, WndMCC.ctr[i].UD,
WndMCC.ctr[i].visible, WndMCC.ctr[i].enabled,
WndMCC.ctr[i].ACTIVATED, WndMCC.ctr[i].hilight, WndMCC.ctr[i].text);
break;
case MC_CHACKBOX:
DrawChackBox (hwnd, hdc, WndMCC.ctr[i].x, WndMCC.ctr[i].y, WndMCC.ctr[i].LR, WndMCC.ctr[i].visible, WndMCC.ctr[i].enabled,
WndMCC.ctr[i].ACTIVATED, WndMCC.ctr[i].hilight, WndMCC.ctr[i].text, WndMCC.ctr[i].MARK);
break;
}
}
void MyMainWindow: OnMouseMoveMyctr (HWND hwnd, UINT uMsg, LPARAM lParam)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
for (WORD i = 0; i < WndMCC.count; i++)
if ((WndMCC.ctr[i].RedrawOnMouseMove == TRUE) /*| (WndMCC.ctr[i].RedrawOnMouseMove == FALSE) */)
{
if (PtInRect(&((WndMCC.ctr[i]).area), pt) && WndMCC.ctr[i].enabled)
{
if((! WndMCC.ctr[i].hilight) /*|((timer==FALSE)& WndMCC.ctr[i].type==7)/*| (WndMCC.ctr[i].ANIMATION==FALSE)*/)
{
/*
if (WndMCC.ctr[i].type==7)
{
WndMCC.ctr[i].ANIMATION=TRUE;
WndMCC.ctr[i].NBitmap=0;
SetTimer (hwnd, IDT_TIMER1,50, (TIMERPROC) NULL);
timer=TRUE;
}
SetTimer (hwnd, // handle to main window
IDT_TIMER1, // timer identifier
10000, // 10-second interval
(TIMERPROC) NULL); // no timer callback
*/
WndMCC.ctr[i].hilight = TRUE;
InvalidateRect (hwnd, &WndMCC.ctr[i].area, FALSE);
}
}
else
if (WndMCC.ctr[i].hilight)
{
/*
if (WndMCC.ctr[i].type==7)
{
WndMCC.ctr[i].ANIMATION=FALSE;
WndMCC.ctr[i].NBitmap=0;
KillTimer (hwnd, IDT_TIMER1);
timer=FALSE;
}
WndMCC.ctr[i].hilight = FALSE;
InvalidateRect (hwnd, &WndMCC.ctr[i].area, FALSE);
}
}
}
void MyMainWindow: OnMouseLBUp (UINT msg, LPARAM lParam)
{
static int lastid = -1;
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
if (msg == WM_LBUTTONDOWN)
{
lastid = -1;
for (WORD i = 0; i < WndMCC.count; i++)
if (PtInRect(&((WndMCC.ctr[i]).area), pt) && (WndMCC.ctr[i].enabled))
{
lastid = i;
//break;
}
}
else
if (msg == WM_LBUTTONUP)
{
for (WORD i = 0; i < WndMCC.count; i++)
if (PtInRect(&(WndMCC.ctr[i]).area, pt) && (lastid == i))
{
lastid = -1;
if (i == CloseBt.id)
{
CloseMyWindow();
}
if (i == MinimizeBt.id)
{
ERRORMSG («dfgdfgdfgdfg»);
MinimizeWnd(); // минимизация окна
}
if (i == File.id)
{
//ERRORMSG («dfgdfgdfgdfg»);
SendMessage (myhwnd, MY_OPEN, NULL, NULL);
//MinimizeWnd(); // минимизация окна
}
if (WndMCC.ctr[i].type==7) // Если это check Box
{int t=4;
for (int k=0; k<=7; k++)
{
}
if (WndMCC.ctr[i].MARK==TRUE)
{WndMCC.ctr[i].MARK = FALSE;
inf [i-t].MARK=FALSE;
information [i-t]=FALSE;
}
else
{WndMCC.ctr[i].MARK = TRUE;
inf [i-t].MARK=TRUE;
information [i-t]=TRUE;
};
RECT r;
r.bottom=330;
r.left=29;
r.right=4600;
r.top=310;
InvalidateRect (myhwnd,&r, FALSE);
SendMessage (myhwnd, WM_PAINT, NULL, NULL);
}
/*
if (id == MinimizeBt.id)
{
ERRORMSG («dfgdfgdfgdfg»); // минимизация окна
}*/
}
}
}
void MyMainWindow: MinimizeWnd()
{
WndMCC. ResetMyctr(myhwnd);
ShowWindow (myhwnd, SW_MINIMIZE);
/*
SendMessage (
myhwnd, // handle to destination window
WM_SETICON, // message to send
ICON_SMALL, // icon type
NULL // handle to icon (HICON)
);
*/
}
void MyMainWindow: CloseMyWindow()
{
ShowWindow (
myhwnd, // handle to window
SW_MINIMIZE // show state
);
SendMessage (myhwnd, WM_CLOSE, 0, 0);
DestroyWindow(myhwnd);
PostQuitMessage(0);
}
void MyMainWindow: OnBottonPress (int id)
{
if (id == CloseBt.id)
{
CloseMyWindow();
}
if (id == MinimizeBt.id)
{
//ERRORMSG («dfgdfgdfgdfg»); // минимизация окна
}
}