CRC-CCITT (0xFFFF) function?

2019-04-08 12:06发布

问题:

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;
 }

回答1:

  • 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



回答2:

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;


回答3:

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/



回答4:

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



回答5:

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.


标签: delphi crc