Verification of a CRC checksum against zero

和自甴很熟 提交于 2021-01-07 01:30:46

问题


I had some contact with the CRC-16 checksum in the past and was accustomed to verifying it by recalculating the CRC-16 checksum over the file I want to verify, plus the 2 bytes of the CRC-16 itself. If the result was zero, then the file integrity was valid, otherwise not.

This can be coded very efficiently like with the following pseudo-C:

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

I recently wanted to use the CRC-32 checksum for a file integrity check and tried to verify it the same way, but it seems like this "Compare-Against-Zero-Trick" is not possible here?!

For example if I use the 32-Bit value 0xDEADBEEF on the CRC online calculator:

  • https://www.lammertbies.nl/comm/info/crc-calculation.html

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

But:

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

Can someone please explain me, why this "Compare-Against-Zero-Trick" does not work for CRC-32?


回答1:


The issue is not that the CRC is 32 bit, but that the CRC is post-complemented, xorout = 0xffffffff. If you append the CRC (little endian), to the message and then compute the CRC again, if there are no errors, the CRC will always be 0x2144DF1C. So in this case you verify the CRC against 0x2144DF1C.

You might find this online CRC calculator a bit more informative, since it shows the parameters: polynomial, xorin, xorout.

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

To explain what is going on, normally if you calculate and append a non-complemented CRC to a message, then calculate the CRC of the message + CRC, the resulting CRC is zero (if there are no errors). Let CRC32X = a custom CRC32 with initial value = 0 and xorout = 0. You can copy and paste the data below with the online CRC calculator I posted a link to.

CRC32X{0x31 0x32 0x33 0x34} = 0xBAA73FBF

appending the CRC and calculating again:

CRC32X{0x31 0x32 0x33 0x34 0xBF 0x3F 0xA7 0xBA} = 0x00000000

Now consider a simpler case:

CRC32X{0x00 0x00 0x00 0x00} = 0x00000000
CRC32X{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00} = 0x00000000

Then to see the effect of complementing the CRC and appending it:

CRC32X{0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF} = 0xDEBB20E3

and taking the complement (using ~ for not):

~CRC32X{0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF} = ~0xDEBB20E3 = 0x2144DF1C

The initial value is XOR'ed with the first 4 bytes of the message. So for CRC32() with initial value of 0xFFFFFFFF, and post complemented CRC:

 CRC32(0x00 0x00 0x00 0x00) = 0x2144DF1C 
~CRC32X(0xFF 0xFF 0xFF 0xFF) = ~0xDEBB20E3 = 0x2144DF1C


来源:https://stackoverflow.com/questions/58393307/verification-of-a-crc-checksum-against-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!