Algorithme CRC – 16 – CCITT

Un autre CRC dans ma bibliothèque est le CRC-16-CCITT ou plus court le CRC-CCITT, je suis tombé sur son utilisation dans
un tourniquet automatique. On peux le retrouver dans X.25, V.41, HDLC FCS, XMODEM, Bluetooth, PACTOR, SD et autres.

Utilisation: crc := CRC_CRTITT(packet);

unit CRC_CCITT;

interface

const
P_CCITT= $1021;
function CRC_CRTITT(packet : tbytes):word;

implementation

var
crc_table: array[0..255] of word;
crc_table_init: boolean = false;

procedure SendByte(B: Byte; var crc: word);
var
tmp, c: word;
begin
c  := $00ff and B;

tmp := (crc shr 8) xor c;
crc := (crc shl 8) xor crc_table[tmp];
end;

procedure MakeTable;
var i, j: Integer;
crc, c: word;
begin
for i := 0 to 255 do begin
crc := 0;
c := i shl 8;
for j := 0 to 7 do begin
if ((crc xor c) and $8000) > 0  then crc := ( crc shl 1 ) xor P_CCITT
else crc := crc shl 1;
c := c shl 1;
end;
crc_table[i] := crc;
end;
crc_table_init := TRUE;
end;

function CRC_CRTITT(packet : tbytes):word;
var
i: integer;
crc: word;
Begin
crc := 0;
if not crc_table_init then MakeTable;

for i := 0 to length(packet)-1 do
begin
SendByte(packet[i], crc);
end;
CRC_CRTITT := CRC;
end;
end.

Algorithme CRC – 16 – IBM

Voici le premier exemple dans la catégorie “CRC Libs”. Un algorithme de calcul de CRC IBM 16bits.
On retrouve cette algorithme dans des protocoles comme Bisync, Modbus, USB, ANSI X3.28, SIA DC-07
et beaucoup d’autres. Il est connu aussi sous le nom CRC-16 et CRC-16-ANSI.

len: la taille du tableau
data: le tableau avec les données

Free Pascal:

function CRC_16_IBM(len: longword; data: TBytes): integer;
var
   num1, i: longword;
   num2: byte;
   j: integer;
begin
  num1 := 0;
  num2 := 0;
  for i := 0 to len-1 do
  begin
    num2 := data[i];
    if i=2 or i=3 then num2 := 0;
    num1 := num1 xor num2;
    for j := 0 to 7 do
      if (num1 and 1) > 0 then
        num1 := (num1 >> 1) xor $a001
      else
        num1 := num1 >> 1;
  end;
  result := num1 and $ffff;
end;   

C#:

public static ushort CRC_16_IBM(uint len, byte[] data)
        {
            uint num1 = 0;
            byte num2 = 0;
            for (uint i = 0; i < len; i++)
            {
                num2 = data[i];
                switch (i)
                {
                    case 2:
                    case 3:
                        num2 = 0;
                        break;
                }
                num1 ^= num2;
                for (uint j = 0; j < 8; j++)
                {
                    if ((num1 & 1) > 0)
                    {
                        num1 = (num1 >> 1) ^ 0xa001;
                    }
                    else
                    {
                        num1 = num1 >> 1;
                    }
                }
            }
            return (ushort)(num1 & 0xffff);
        }