验证CRC校验和是否为零

use*_*464 1 c crc32 checksum crc crc16

我过去与CRC-16校验和有过联系,习惯于通过对要验证的文件以及CRC-16本身的2个字节重新计算CRC-16校验和来进行验证。如果结果为零,则文件完整性有效,否则无效。

可以像下面的伪C一样非常有效地进行编码:

if (recalculated_crc16_checksum != 0) // Error: file integrity is corrupt else // Success: file integrity is valid

我最近想使用CRC-32校验和进行文件完整性检查,并尝试以相同的方式进行验证,但似乎这里“ Compare-Against-Zero-Trick”是不可能的?

例如,如果我在CRC在线计算器上使用32位值0xDEADBEEF:

CRC-16-Modbus(0xDEADBEEF) = 0xC19B (Same input value but with appended checksum 0xC19B in reversed byte ordering) CRC-16-Modbus(0xDEADBEEF9BC1) = 0x0000

但:

CRC-32(0xDEADBEEF) = 0x7C9CA35A (I tried both: big and little endian byte ordering for the appended checksum) CRC-32(0xDEADBEEF7C9CA35A) = 0x01F92292 != 0x00000000 CRC-32(0xDEADBEEF5AA39C7C) = 0x2144DF1C != 0x00000000

有人可以向我解释一下,为什么此“ Compare-Against-Zero-Trick”不适用于CRC-32吗?

rcg*_*ldr 6

问题不在于CRC是32位,而是CRC是后补码的xorout = 0xffffffff。如果将CRC(小尾数)附加到消息中,然后再次计算CRC,如果没有错误,则CRC始终为0x2144DF1C。因此,在这种情况下,您需要针对0x2144DF1C验证CRC。

您可能会发现此在线CRC计算器更具信息性,因为它显示了以下参数:多项式,xorin,xorout。

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

为了解释所发生的情况,通常,如果您计算并在消息中附加非互补的CRC,然后计算消息的CRC + CRC,则得到的CRC为零(如果没有错误)。设CRC32X =初始值= 0且xorout = 0的自定义CRC32。您可以使用我发布链接的在线CRC计算器复制和粘贴以下数据。

CRC32X{0x31 0x32 0x33 0x34} = 0xBAA73FBF
Run Code Online (Sandbox Code Playgroud)

附加CRC并再次计算:

CRC32X{0x31 0x32 0x33 0x34 0xBF 0x3F 0xA7 0xBA} = 0x00000000
Run Code Online (Sandbox Code Playgroud)

现在考虑一个更简单的情况:

CRC32X{0x00 0x00 0x00 0x00} = 0x00000000
CRC32X{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00} = 0x00000000
Run Code Online (Sandbox Code Playgroud)

然后查看补充CRC并将其附加的效果:

CRC32X{0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF} = 0xDEBB20E3
Run Code Online (Sandbox Code Playgroud)

并取补码(不使用〜):

~CRC32X{0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF} = ~0xDEBB20E3 = 0x2144DF1C
Run Code Online (Sandbox Code Playgroud)

初始值与消息的前4个字节进行XOR运算。因此对于初始值为0xFFFFFFFF且后补CRC的CRC32():

 CRC32(0x00 0x00 0x00 0x00) = 0x2144DF1C 
~CRC32X(0xFF 0xFF 0xFF 0xFF) = ~0xDEBB20E3 = 0x2144DF1C
Run Code Online (Sandbox Code Playgroud)