Реализация алгоритма обнаружения ошибок Код Хэминга

Программа, наглядно показывающую работу кода Хэмминга.

При старте программы вводится последовательность бит, которые должны быть переданы. Программа кодирует их по Хэммингу, и выводит результат - последовательность бит, готовую к передаче (при этом красным цветом выделены "избыточные" биты, не несущие информации, а используемые только для отслеживания ошибки).

Затем вводится строка битов, полученная приемником информации, и после ее анализа выводится результат - есть ли ошибка, и в какой именно бите... (биты нумеруются СЛЕВА НАПРАВО (!!!) начиная с единицы).

Вот лог работы программы: 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

code: #pascal
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

Поделиться:

Похожие статьи: