Московский государственный институт электроники и математики

Кафедра ИКТ

курсовая работа по дисциплине «Теория

информации и кодирования»

Код Хемминга

Выполнил:

Руководитель:

Москва 2009
Оглавление

Оглавление........................................................................................................................................ 2

Задание............................................................................................................................................... 3

Теоретические сведения.................................................................................................................. 3

Алгоритм программы..................................................................................................................... 4

Код программы................................................................................................................................ 5


Задание

Составить и отладить программу для кодирования и декодирования двоичных чисел кодом Хемминга с коррекцией.

Теоретические сведения

Коды Хемминга являются наиболее эффективными для коррекции одиночных ошибок (dmin=3) и для обнаружения двойной и коррекции одиночной (dmin=4).

В кодах Хемминга по определенным правилам производится разбиение на подмножества, и в соответствие контрольному разряду записывается дополнение до четности. При декодировании проверяется четность по подмножествам и, на основании полученной информации определяется номер искаженных разрядов.

НЕ нашли? Не то? Что вы ищете?

В кодах Хемминга с dmin=4 выделяется еще один дополнительный контрольный разряд, куда записывается дополнение до четности всего кодового слова в целом. При декодировании проверяется четность как по основным подмножествам, так и всего слова в целом.

Для построения Кодов Хемминга достаточно приписать к каждому слову один добавочный (контрольный) двоичный разряд и выбрать цифру такого разряда так, чтобы общее количество единиц в изображении любого числа было, например, четным. Одиночная ошибка в каком-либо разряде передаваемого слова (в том числе, может быть, и в контрольном разряде) изменит четность общего количества единиц. Счетчики по модулю 2, подсчитывающие количество единиц, которые содержатся среди двоичных цифр числа, могут давать сигнал о наличии ошибок.

Можно построить и такой код, который обнаруживал бы двойные ошибки и исправлял одиночные. Для этого к коду, рассчитанному на исправление одиночных ошибок, нужно приписать еще один контрольный разряд (разряд двойного контроля). Полное количество разрядов кода при этом будет m+k+1. Цифра в разряде двойного контроля устанавливается такой, чтобы общее количество единиц во всех m + k + 1 разрядах кода было четным. Этот разряд не включается в общую нумерацию и не входит ни в одну контрольную группу.

При этом могут быть следующие случаи:

1. В принятом коде в целом и по всем контрольным группам количество единиц четно. Если тройные ошибки и ошибки в большем количестве разрядов исключаются, то первый случай соответствует безошибочному приему кода.

2. В принятом коде в целом количество единиц нечетно, но во всех контрольных группах количество единиц четно. Второй случай - ошибки только в разряде двойного контроля.

3. В принятом коде в целом и в некоторых из контрольных групп количество единиц нечетно. Третий случай — одиночной ошибки в каком-либо из остальных разрядов

4. В принятом коде в целом количество единиц четно, но в некоторых контрольных группах имеется нечетное количество единиц - двойная ошибка. Исправление двойных ошибок невозможно.

Алгоритм программы

Программа кодировщик работает следующим образом :

Вводится входное слово, после чего в массив со словом добавляются пустые ячейки для контрольных разрядов. После этого входное слово разбивается на подмножества в которых считается сумма по модулю два, а результат записывается в соответствующую подмножеству ячейку массива. После чего берется сумма по модулю два от закодированного слова и в зависимости от результата в конец слова записывается 0 или 1 как дополнение до четности (в случае с dмин=4).

Программа декодировщик работает следующим образом:

Программа считает контрольные разряды снова, точно так же как это делал кодировщик, после чего она сравнивает посчитанные контрольные разряды с теми контрольными разрядами, которые были введены с закодированным словом, если контрольный разряд отличается, то в регистр ошибок записывается 1 на соответствующее место.

Если выражение в регистре ошибок равняется 0000 и совпала проверка четности слова, то ошибок нет.
Если выражение в регистре ошибок равно 0000 и не совпала проверка четности, то это значит, что в закодированном слове имеется одиночная ошибка в месте, где указывает выражение регистра ошибок.
Если выражение в регистре ошибок не равно 0000 ,а проверка четности совпал, то это значит что в закодированном слове двоичная ошибка, обнаружить которую невозможно.

Код программы

Кодирование

<?php

$a = array();

$str = $_POST['qq'];

for ($i=strlen($str)-1; $i>-1; $i--)

$a[]=$str[$i];

$aa = array();

$j = 0;

$i = 0;

$ii = 0;

while (1)

{

if (pow(2, $j) == ($i+1)) {$aa[]=5; $j++; } else {$aa[]=$a[$ii]; $ii++;}

if ($ii == count($a)) break;

$i++;

}

$aaa = $aa;

$kk = array();

$ppc = array();

for ($i=0; $i<$j; $i++)

{

$sum = 0;

$fg = 1;

$flag = false;

for ($k=0; $k<count($aa); $k++)

{

if ($fg == pow(2, $i)) {$flag = !$flag; $fg = 0;}

$fg++;

if ($flag && $aa[$k] != 5) {$ppc[$i][$k] = 5; $sum = $sum + $aa[$k];} else $ppc[$i][$k] = 'v';

if ($flag && $aa[$k] == 5) {$kk[$i]=$k;}

}

$aa[$kk[$i]] = $sum & 1;

}

echo '<table border="0"><tr><td bgcolor="#CCCCFF">Номера разрядов</td>';

for ($i=count($ppc[1]); $i>0; $i--)

echo "<td bgcolor='#CCCCFF'>".$i."</td>";

echo "</tr><tr><td bgcolor='#CCCCFF'>Число А</td>";

for ($t=count($aaa)-1; $t>-1; $t--)

if ($aaa[$t] == 5)

echo "<td bgcolor='#EEEEEE'>&nbsp;</td>";

else

echo "<td bgcolor='#CCCCCC'>".$aaa[$t]."</td>";

for ($i=0; $i<count($ppc); $i++)

{

echo '<tr><td bgcolor="#CCCCFF">Подмножество '.($i+1).'</td>';

for ($j=count($ppc[1])-1; $j>-1; $j--)

//for ($j=0; $j<count($ppc[1]); $j++)

{

echo "<td width='10'";

if ($ppc[$i][$j] == 5) echo 'bgcolor="#CCCCCC">'.$aa[$j].'</td>';

else if ($kk[$i] == $j) echo 'bgcolor="#FFCCCC">'.$aa[$j].'</td>';

else echo "bgcolor='#EEEEEE'>&nbsp;</td>";

}

echo '</tr>';

}

echo "<tr><td bgcolor='#CCCCFF'>Число А в коде Хэмминга c Dmin=3</td>";

$j = count($kk)-1;

for ($i=count($aa)-1; $i>-1; $i--) {

//for($i=0; $i<count($aa); $i++) {

echo "<td ";

if ($kk[$j] == $i) {echo 'bgcolor="#FFCCCC"'; $j--;} else echo 'bgcolor="#CCCCCC"';

echo ">".$aa[$i]."</td>";

}

$sum2=0;

for ($i=0; $i<count($aa); $i++)

$sum2=$sum2+$aa[$i];

$sum2=$sum2 & 1;

echo "<tr><td bgcolor='#CCCCFF'>Число А в коде Хэмминга c Dmin=4</td>";

$j = count($kk)-1;

for ($i=count($aa)-1; $i>-1; $i--) {

//for($i=0; $i<count($aa); $i++) {

echo "<td ";

if ($kk[$j] == $i) {echo 'bgcolor="#FFCCCC"'; $j--;} else echo 'bgcolor="#CCCCCC"';

echo ">".$aa[$i]."</td>";

}

echo "<td bgcolor='#CCFFCC'>".$sum2."</td>";

echo '</td></table><br>Число А в коде Хэмминга c Dmin=4 - ';

for ($i=count($aa)-1; $i>-1; $i--)

echo $aa[$i];

echo $sum2;

?>

Декодирование

<?php

$a = array();

$str = $_POST['q'];

function rep(array $q)

{

$sum=0;

for ($i=0; $i<count($q); $i++)

{

if ($q[$i]==1) $sum=$sum + pow(2, ($i));

}

return $sum;

}

for ($q=strlen($str)-2; $q>-1; $q--)

$aa[]=$str[$q];

$j = 0;

while(1)

{

if (pow(2, ($j)) > count($aa)) {break;} else $j++;

}

$aaa = $aa;

$error = array();

$kk = array();

$ppc = array();

for ($i=0; $i<$j; $i++)

{

$sum = 0;

$fg = 1;

$flag = false;

for ($k=0; $k<count($aa); $k++)

{

if ($fg == pow(2, $i)) {$flag = !$flag; $fg = 0;}

$fg++;

if ($flag && $aa[$k] != 5) {$ppc[$i][$k] = 5; $sum = $sum + $aa[$k];} else $ppc[$i][$k] = 'v';

if ($flag && $aa[$k] == 5) {$kk[$i]=$k;}

}

if ($aa[$kk[$i]] != ($sum & 1)) $error[]=1; else $error[]=0;

}

$sum=$str[strlen($str)-1];

for ($i=0; $i<count($aa); $i++)

{

$sum=$sum+$aa[$i];

}

$lolq = 0;

if (($sum & 1) == 0 && rep($error) == 0) echo "Ошибок не произошло";

if (($sum & 1) == 1 && rep($error) == 0) {echo "Ошибка произощла в 0 разряде (бит четности всего слова)"; $lolq = 1;}

if (($sum & 1) == 0 && rep($error) != 0) echo "Произошла двоичная ошибка<br>Определить место положение ошибок не удалось =(";

if (($sum & 1) == 1 && rep($error) != 0) echo "Произошла одиночная ошибка в ".rep($error)." разряде";

$omg = count($aa)-rep($error);

//$aa[rep($error)-1] = !$aa[rep($error)];

echo '<table>

<tr>

<td bgcolor="#CCCCFF">Номер разряда</td>';

for ($i=(count($aa)); $i>-1; $i--)

{echo "<td bgcolor='#CCCCFF'>".$i."</td>"; if ($omg == $i) $omg2 = $i;}

echo '</tr><tr>';

echo '<td bgcolor="#CCCCFF">Введенное слово</td>';

for ($i=(count($aa)-1); $i>-1; $i--)

{if ((count($aa)-1-$omg2) == $i) echo "<td bgcolor='#FFCCCC'>".$aa[$i]."</td>"; else echo "<td bgcolor='#CCFFCC'>".$aa[$i]."</td>";}

if ($lolq == 1)echo "<td bgcolor='#FFCCCC'>".$str[strlen($str)-1]."</td></tr></table>"; else

echo "<td bgcolor='#CCFFCC'>".$str[strlen($str)-1]."</td></tr></table>";

echo "Сигнатура указывающая на ошибку - ";

for ($d=(count($error)-1); $d>-1; $d--)

echo $error[$d];

;

?>