Реализация алгоритма обнаружения ошибок Код Хэминга
Программа, наглядно показывающую работу кода Хэмминга.
При старте программы вводится последовательность бит, которые должны быть переданы. Программа кодирует их по Хэммингу, и выводит результат - последовательность бит, готовую к передаче (при этом красным цветом выделены "избыточные" биты, не несущие информации, а используемые только для отслеживания ошибки).
Затем вводится строка битов, полученная приемником информации, и после ее анализа выводится результат - есть ли ошибка, и в какой именно бите... (биты нумеруются СЛЕВА НАПРАВО (!!!) начиная с единицы).
Вот лог работы программы:
sent data [7] bits: 1110011
1 1 1 1 0 0 1 1 1 1 0
checking error status [0 = no error]: 0
received data [11] bits: 11111011110
checking error status [0 = no error]: 5
uses crt; const data_len = 7; type PTBlock = ^TBlock; TBlock = array[1 .. maxint] of byte; function is_power(x: byte): boolean; var bits: byte; begin bits := 0; while x > 0 do begin if (x and $01) = $01 then inc(bits); x := x shr 1; end; is_power := (bits = 1); end; procedure print_block(X: PTBlock; const n: byte); var i: byte; begin for i := n downto 1 do begin if is_power(i) then textcolor(lightred) else textcolor(lightgray); write(X^[i]:4); end; writeln; textcolor(lightgray); end; var ctrl_bits: byte; block: PTBlock; s: string; check, i, pos: byte; begin ctrl_bits := 0; repeat inc(ctrl_bits); until (data_len + ctrl_bits + 1) <= (1 shl ctrl_bits); writeln('p = ', ctrl_bits); GetMem(block, (data_len + ctrl_bits)*sizeof(byte)); FillChar(block^, (data_len + ctrl_bits)*sizeof(byte), 0); Write('sent data [', data_len, '] bits: '); ReadLn(s); pos := 1; for i := 1 to data_len do begin while is_power(pos) do inc(pos); block^[pos] := (ord(s[data_len - i + 1]) - ord('0')); inc(pos); end; check := $00; for i := 1 to (data_len + ctrl_bits) do if block^[i] = 1 then check := check xor i; i := 1; while check > 0 do begin block^[i] := (check and $01); check := check shr 1; i := 2 * i end; print_block(block, (data_len + ctrl_bits)); { Проверка правильности } check := $00; for i := 1 to (data_len + ctrl_bits) do if block^[i] = 1 then check := check xor i; writeln('checking error status [0 = no error]: ', check); writeln; Write('received data [', data_len + ctrl_bits, '] bits: '); ReadLn(s); check := $00; for i := 1 to (data_len + ctrl_bits) do if s[(data_len + ctrl_bits) - i + 1] = '1' then check := check xor i; writeln('checking error status [0 = no error]: ', (data_len + ctrl_bits) - check + 1); FreeMem(block, (data_len + ctrl_bits)*sizeof(byte)); ReadLn; end.
автор: volvo