我正在开发一个轻量级 CRC 计算器,适用于我在在线目录中找到的所有 8 位、16 位和 32 位版本:
https://reveng.sourceforge.io/crc-catalogue/all.htm
我对
residue
参数感到困惑。据我了解,它的值定义了计算整个消息及其 CRC 时的 CRC 寄存器值。但是,我无法让此检查适用于某些(大多数)算法。
我们可以使用以下在线工具进行快速检查:
我们可以使用标准测试消息
b"123456789"
,它是十六进制的0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39
。当为此消息计算 CRC 时,结果等于 check
参数。现在,如果我将 check
参数附加到标准测试消息中,我期望获得 residue
参数。然而,这对于大约一半的算法不起作用。
这是当我输入标准测试消息加上该特定算法的检查参数时收到的几条消息的示例。
==========================================================================
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*
==========================================================================
但是,只要将 CRC 附加到消息中,
CRC-16/DNP
似乎就会总是 导致0x993A
。其他算法也类似。
我在这里缺少什么?
余数被定义为应用最终异或之前的 CRC。 CRC-16/DNP 的最终异或是 0xffff
。
0x66c5
的补码是
0x993a
。从表中您可以看到,当 CRC 字节以正确的顺序附加时(并且当最终的异或为零时,因为您没有考虑到这一点),它可以工作。当 CRC 被反映时,正确的顺序是小端,当没有反映时,正确的顺序是大端。