【问题标题】:How to get ethernet magical number 0xC704DD7B from zlib crc32 calculator如何从 zlib crc32 计算器中获取以太网幻数 0xC704DD7B
【发布时间】:2020-05-14 04:12:02
【问题描述】:

我从this answer(稍作修改)拿了一个python sn-p来计算一个以太网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))

对于消息00,它输出8D EF 02 D2,这是this answer 的位反转解决方案。到目前为止一切顺利。

现在据说here,那个

对接收到的帧数据(包括 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

那么,谁能告诉我,我哪里错了?

【问题讨论】:

    标签: python zlib ethernet crc crc32


    【解决方案1】:

    Wiki 文章中的 0xC704DD7B 是 0x2144DF1C 的位反转和补码,这是您得到的值,也是您应该得到的值。

    在 CRC32 的情况下,由于 CRC 是后补的,因此对数据执行的“良好”CRC 重新计算 + 先前计算的 CRC 将是一个非零常数,在本例中为 0x2144DF1C。这不是一个“幻数”,一个好的 CRC 的非零常数值是对 CRC 进行后补的结果(否则一个好的重新计算的 CRC 将为零)。


    令人困惑的是,IEEE 标准使用左移 CRC32 BZIP2(非反转)CRC 来创建 CRC,然后声明数据首先传输最低有效位,而 CRC(称为 FCS(帧校验序列))首先传输最高有效位(第 31 位)。使用右移 CRC32(反转)CRC 产生相同的 CRC,但位反转,并且首先传输数据和 CRC 最低有效位会导致相同的传输。所以根据实际的实现,CRC可能会反转或不反转,如果使用硬件寄存器中的“残差”,可能会或可能不会被补充。

    Wiki 文章现已更新以包含这些问题。

    【讨论】:

      猜你喜欢
      • 2012-03-06
      • 1970-01-01
      • 2015-03-18
      • 2020-04-03
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 2015-04-12
      相关资源
      最近更新 更多