crc

CRC residue verification fails


I am developing a light-weight CRC calculator for all 8-, 16-, and 32-bit versions that I found in the online catalogue:

https://reveng.sourceforge.io/crc-catalogue/all.htm

I'm confused by the residue parameter. As I understand, its value defines the CRC register value when it is calculated for the whole message plus its CRC. However, I cannot get this check to work for some (most) algorithms.

We can use the following online tool for a quick check:

https://crccalc.com/

We can use the standard test message b"123456789" which is in hex 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39. When CRC is calculated for this message, the result equals the check parameter. Now if I append the check parameter to the standard test message, I expect to get the residue parameter. However, this does not work for about half the algorithms.

Here is an example what I get for couple of messages when I input the standard test message plus the check parameter for that particular algorithm.

==========================================================================
Algorithm        Check    Append      Residue  Result for TEST + Append
==========================================================================
CRC-16/ARC       0xBB3D   0x3D 0xBB   0x0000   0x0000
CRC-16/ARC       0xBB3D   0xBB 0x3D   0x0000   0xC2E3    *DOES NOT MATCH*
--------------------------------------------------------------------------
CRC-16/CDMA2000  0x4C06   0x06 0x4C   0x0000   0xA527    *DOES NOT MATCH*
CRC-16/CDMA2000  0x4C06   0x4C 0x06   0x0000   0x0000
--------------------------------------------------------------------------
CRC-16/DNP       0xEA82   0x82 0xEA   0x66C5   0x993A    *DOES NOT MATCH*
CRC-16/DNP       0xEA82   0xEA 0x82   0x66C5   0x2BD4    *DOES NOT MATCH*
==========================================================================

However, the CRC-16/DNP does seem to always result in 0x993A whenever the CRC is appended to the message. It is similar for other algorithms.

What am I missing here?


Solution

  • The residue is defined to be the CRC before the final exclusive-or is applied. The final exclusive-or for CRC-16/DNP is 0xffff. The complement of 0x66c5 is 0x993a.

    From your table you can see that it works when the CRC bytes are appended in the correct order (and when the final exclusive-or is zero, since you weren't taking that into account). The correct order is little-endian when the CRC is reflected, and big-endian when it is not reflected.