sorry - am Freitag spät Abends war ich platt, aber ich hatte eine Lösung!
Bist du sicher, dass deine Lösung richtig ist?
Delphi-Quellcode:
function CAL_CRC_CCITT_XMODEM(data: PByte; len: Integer): Word;
const
poly = $1021;
var
i, j: Integer;
crc: Word;
begin
crc := 0;
for i := 0 to len-1 do
begin
crc := crc xor (Word(data^) shl 8);
for j := 0 to 7 do
begin
if (crc and $8000) > 0 then
crc := (crc shl 1) xor poly
else
crc := crc shl 1;
end;
Inc(data);
end;
Result := crc;
end;
Deine Interpretation entspricht
nicht dem C-Code aus dem ersten Post. Ein einfacher automatisierter Test über 1M Runden ergibt bei mir ca. >25K Konflikte.
Delphi-Quellcode:
{$R-}
function CalcCRC(pmPText: PAnsiChar): Word;
const
CRC_TABLE: array[0..15] of Word = (
$0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7,
$8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef);
var
idx: Byte;
crc: WordRec absolute Result;
begin
Result := 0;
if pmPText = Nil then Exit; //=>
while pmPText^ <> #0 do
begin
idx := (Result shr 12) xor (Ord(pmPText^) shr 4);
Result := (Result shl 4) xor CRC_TABLE[idx];
idx := (Result shr 12) xor (Ord(pmPText^) and $0f);
Result := (Result shl 4) xor CRC_TABLE[idx];
Inc(pmPText);
end;
if (crc.Lo = $28) or (crc.Lo = $0d) or (crc.Lo = $0a) then
Inc(crc.Lo);
if (crc.Hi = $28) or (crc.Hi = $0d) or (crc.Hi = $0a) then
Inc(crc.Hi);
end;
{$R+}
var
txt: AnsiString;
begin
for var i: Integer := 0 to 1000000 do
begin
txt := TSynTestCase.RandomIdentifier(1 + Random(20));
if CalcCRC(Pointer(txt)) <> CAL_CRC_CCITT_XMODEM(Pointer(txt), Length(txt)) then
TSynLog.Add.Log(sllInfo, Utf8ToString(txt));
Teste deine Version mal gegen das C-Original für folgende Eingaben: YO, ZOL, DIHN, VRY77, PK20OM, 6A07EBH
Bis bald...
Thomas