2
votes

I've written two simple button handlers to test/demonstrate CRC16 and CRC32 from the Delphi Encryption Compendium 5.2. The code for CRC16 works fine, but the validation for CRC32 allways fails.

I'm using a 512 byte array where the last 2 or 4 bytes (for crc16 or crc32) are reserved for the checksum. Whats wrong with the code for CRC-32? My first idea was that there is an issue with byte order, but then crc16 code should fail, too.

procedure TForm3.CRC16Click(Sender: TObject);
var
  LData: array[1..512] of Byte;
    FSum: Cardinal;
  FIntPtr: Pointer;
begin
  FillChar(LData, sizeof(LData), 0);
  LData[1] := $FF; // set some test data

  FSum := CRCCalc(CRC_16, LData, (SizeOf(LData)-sizeof(Word)));

  FIntPtr := @LData[512-1]; // don't get confused by -1...

  PWord(FIntPtr)^ := FSum and $FFFF;
  Assert( CRCCalc(CRC_16, LData, (SizeOf(LData))) = 0); // THIS WORKS!
end;

procedure TForm3.CRC32Click(Sender: TObject);
var
  LData: array[1..512] of Byte;
    FSum: Cardinal;
  FIntPtr: Pointer;
begin
  FillChar(LData, sizeof(LData), 0);
  LData[1] := $FF; // set some test data

  FSum := CRCCalc(CRC_32, LData, (SizeOf(LData)-sizeof(Cardinal)));

  FIntPtr := @LData[512-3]; // don't get confused by -3...

  PCardinal(FIntPtr)^ := FSum;
  Assert( CRCCalc(CRC_32, LData, (SizeOf(LData))) = 0); // ASSERT FAILURE! <<<
end;
1

1 Answers

1
votes

Your assertion is based on the following property holding:

CRC(arr + [CRC(arr)]) = 0

where I am using + to indicate array concatenation.

I believe that the particular CRC32 implementation that DEC exposes does not have this property. DEC offers three CRC32 variants, named CRC_32, CRC_32CCITT and CRC_32ZModem. Only CRC_32ZModem has the property that you assert.

Serg suggests that you should be asserting that:

not CRC(arr + [not CRC(arr)]) = 0

which holds for CRC_32 and CRC_32CCITT, but not for CRC_32ZModem.