Pet*_*rdt 1 python crc32 ethernet zlib crc
我从这个答案中获取了一个Python片段(稍加修改)来计算以太网crc32帧检查序列:
msg = '00'
data = bytes.fromhex(msg)
print(data)
print(msg)
crc = zlib.crc32(data)&0xFFFFFFFF
for i in range(4):
b = (crc >> (8*i)) & 0xFF
print('{:02X}'.format(b))
Run Code Online (Sandbox Code Playgroud)
00对于它输出的消息,这是此答案8D EF 02 D2的位反转解决方案。到目前为止,一切都很好。
现在这里说,
对包括 CRC 码的接收帧数据运行 CRC 算法将始终导致无错误接收数据的零值,因为 CRC 是数据除以多项式的余数。然而,这种技术可能无法检测错误,其中带有尾随零的数据也将导致相同的零余数。为了避免这种情况,发送方在将 FCS 附加到有效负载数据的末尾之前对其进行补充(每个位都取反)。这样,当数据正确接收时,算法结果将始终是 0xC704DD7B 的 CRC32 残差。
但如果我输入00 8D EF 02 D2计算器,结果是1C DF 44 21,而不是所说的余数。我还尝试了其他组合,因为通常必须反转字节中的位或其他什么(我实际上对所有这些反转的东西感到困惑,但我希望,尝试几种可能性后的良好结果将引导我走向正确的反转),但没有任何成功:
00 D8 FE 20 2D -> 66 40 C3 4A
00 D2 02 EF 8D -> DF 42 14 03
00 2D 20 FE D8 -> CB 50 00 AE
Run Code Online (Sandbox Code Playgroud)
那么,谁能告诉我,我错在哪里?
Wiki 文章中的 0xC704DD7B 是 0x2144DF1C 的位反转和补码,这是您正在获取的值和您应该获取的值。
在 CRC32 的情况下,由于 CRC 是后补的,因此对数据 + 先前计算的 CRC 执行的“良好”CRC 重新计算将是一个非零常数,在本例中为 0x2144DF1C。它不是一个“神奇数字”,良好 CRC 的非零常量值是对 CRC 进行后补的结果(否则重新计算的良好 CRC 将为零)。
令人困惑的是,IEEE 标准使用左移 CRC32 BZIP2(非反向)CRC 来创建 CRC,然后规定数据首先传输最低有效位,而 CRC(称为 FCS(帧校验序列))则传输最多首先是有效位(位 31)。使用右移 CRC32(反转)CRC 会产生相同的 CRC,但位反转,并且首先传输数据和 CRC 最低有效位会导致相同的传输。因此,根据实际实现,CRC 可能会被反转,也可能不会,并且如果使用硬件寄存器中的“余数”,则可能会或可能不会被补足。
维基文章现已更新以包含这些问题。