Dels
Dels

Reputation: 2425

CRC-CCITT (0xFFFF) function?

Can someone help me with Delphi implementation of CRC-CCITT (0xFFFF)?

Already get the Java version, but confusing on how to port it to Delphi

public static int CRC16CCITT(byte[] bytes) {
    int crc = 0xFFFF;          // initial value
    int polynomial = 0x1021;   // 0001 0000 0010 0001  (0, 5, 12) 

    for (byte b : bytes) {
        for (int i = 0; i < 8; i++) {
            boolean bit = ((b   >> (7-i) & 1) == 1);
            boolean c15 = ((crc >> 15    & 1) == 1);
            crc <<= 1;
            if (c15 ^ bit) crc ^= polynomial;
         }
    }

    crc &= 0xffff;
    //System.out.println("CRC16-CCITT = " + Integer.toHexString(crc));
    return crc;
}

and for PHP implementation

<?php
function crc16($data)
 {
   $crc = 0xFFFF;
   for ($i = 0; $i < strlen($data); $i++)
   {
     $x = (($crc >> 8) ^ ord($data[$i])) & 0xFF;
     $x ^= $x >> 4;
     $crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF;
   }
   return $crc;
 }

Upvotes: 5

Views: 15343

Answers (5)

Remy Lebeau
Remy Lebeau

Reputation: 595712

function CRC16CCITT(bytes: TBytes): Word;
const
  polynomial = $1021;   // 0001 0000 0010 0001  (0, 5, 12)
var
  crc: Word;
  I, J: Integer;
  b: Byte;
  bit, c15: Boolean;
begin
  crc := $FFFF; // initial value
  for I := 0 to High(bytes) do
  begin
    b := bytes[I];
    for J := 0 to 7 do
    begin
      bit := (((b shr (7-J)) and 1) = 1);
      c15 := (((crc shr 15) and 1) = 1);
      crc := crc shl 1;
      if ((c15 xor bit) <> 0) then crc := crc xor polynomial;
    end;
  end;
  Result := crc and $ffff;
end;

Upvotes: 9

Vladimir Poslavskiy
Vladimir Poslavskiy

Reputation: 146

unit CRC16CCITT;

interface

  function ComputeCRC16CCITT(crc: word; const data: PByte; len:integer) : word;

implementation

const
  crc16_table: array [0..$FF] of word = (0,4489,8978,12955,17956,22445,25910,29887,35912,40385,44890,48851,51820,56293,59774,
    63735,4225,264,13203,8730,22181,18220,30135,25662,40137,36160,49115,44626,56045,52068,63999,
    59510,8450,12427,528,5017,26406,30383,17460,21949,44362,48323,36440,40913,60270,64231,51324,
    55797,12675,8202,4753,792,30631,26158,21685,17724,48587,44098,40665,36688,64495,60006,55549,
    51572,16900,21389,24854,28831,1056,5545,10034,14011,52812,57285,60766,64727,34920,39393,43898,
    47859,21125,17164,29079,24606,5281,1320,14259,9786,57037,53060,64991,60502,39145,35168,48123,
    43634,25350,29327,16404,20893,9506,13483,1584,6073,61262,65223,52316,56789,43370,47331,35448,
    39921,29575,25102,20629,16668,13731,9258,5809,1848,65487,60998,56541,52564,47595,43106,39673,
    35696,33800,38273,42778,46739,49708,54181,57662,61623,2112,6601,11090,15067,20068,24557,28022,
    31999,38025,34048,47003,42514,53933,49956,61887,57398,6337,2376,15315,10842,24293,20332,32247,
    27774,42250,46211,34328,38801,58158,62119,49212,53685,10562,14539,2640,7129,28518,32495,19572,
    24061,46475,41986,38553,34576,62383,57894,53437,49460,14787,10314,6865,2904,32743,28270,23797,
    19836,50700,55173,58654,62615,32808,37281,41786,45747,19012,23501,26966,30943,3168,7657,12146,
    16123,54925,50948,62879,58390,37033,33056,46011,41522,23237,19276,31191,26718,7393,3432,16371,
    11898,59150,63111,50204,54677,41258,45219,33336,37809,27462,31439,18516,23005,11618,15595,3696,
    8185,63375,58886,54429,50452,45483,40994,37561,33584,31687,27214,22741,18780,15843,11370,7921,
    3960);

  function ComputeCRC16CCITT(crc: word; const data: PByte; len:integer) : word;
  var
    i : integer;
  begin
    for i := 0 to len-1 do  
      crc := (crc shr 8) xor crc16_table[(crc xor data[i]) and $ff];
    result := crc;
  end;

end.

Upvotes: 1

Dels
Dels

Reputation: 2425

i found some code that works:

function crc16(Buffer:String;Polynom,Initial:Cardinal):Cardinal;
var
  i,j: Integer;
begin
Result:=Initial;
for i:=1 to Length(Buffer) do begin
  Result:=Result xor (ord(buffer[i]) shl 8);
  for j:=0 to 7 do begin
    if (Result and $8000)<>0 then Result:=(Result shl 1) xor Polynom
    else Result:=Result shl 1;
    end;
  end;
Result:=Result and $ffff;
end;

source : http://www.miscel.dk/MiscEl/CRCcalculations.html

Upvotes: 4

TridenT
TridenT

Reputation: 4909

You can find one in Delphi Encryption Compendium (DEC) component.

5 Checksums (CRC32, CRC16-CCITT, CRC16-Standard ...)

http://blog.digivendo.com/2008/11/delphi-encryption-compendium-dec-52-for-d2009-released/

Upvotes: 5

Barry Kelly
Barry Kelly

Reputation: 42152

  • 0xFFFF translates to $FFFF
  • & translates to and
  • ^ translates to xor
  • << translates to shl
  • >> translates to shr
  • x ^= y translates to x := x xor y, similar for &=, <<=, etc.

These operators generally have higher precedence in Delphi so they usually need to have their arguments parenthesized.

I'm quite sure that there are plenty of other implementations of CRC16 etc. for Delphi, see e.g. Improve speed on Crc16 calculation

Upvotes: 12

Related Questions