问题
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 toand
^
translates toxor
<<
translates toshl
>>
translates toshr
x ^= y
translates tox := 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.
来源:https://stackoverflow.com/questions/5139480/crc-ccitt-0xffff-function