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:
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?
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.