我正在尝试逐字节计算以太网数据包的帧校验序列(FCS)。多项式是0x104C11DB7
。我确实遵循了这里看到的 XOR-SHIFT 算法http://en.wikipedia.org/wiki/Cyclic_redundancy_check或这里http://www.woodmann.com/fravia/crctut1.htm
假设应该有 CRC 的信息只有一个字节。假设它是0x03。
step:向右填充 32 位
0x0300000000
将左侧的多项式和数据与其第一个不为零的位对齐,然后对它们进行异或
0x300000000 xor 0x209823B6E = 0x109823b6e
取余数对齐并再次异或
0x109823b6e xor 0x104C11DB7 = 0x0d4326d9
由于没有更多位,0x03 的 CRC32 应该是0x0d4326d9
不幸的是,所有的软件实现都告诉我我错了,但我做错了什么或者他们做错了什么?
Python告诉我:
"0x%08x" % binascii.crc32(chr(0x03))
0x4b0bbe37
此处的在线工具http://www.lammertbies.nl/comm/info/crc-calculation.html#intr得到相同的结果。我的手工计算与上述软件使用的算法有什么区别?
更新:
原来在堆栈溢出时已经有一个类似的问题:
你在这里找到答案Python CRC-32 woes
虽然这不是很直观。如果您想更正式地描述如何处理以太网帧,可以查看以太网标准文档 802.3 Part 3 - Chapter 3.2.9 Frame Check Sequence Field
让我们继续上面的例子:
反转消息的位顺序。这代表了它们将一点一点地进入接收器的方式。
0x03
因此是0xC0
补充消息的前 32 位。请注意,我们再次用 32 位填充单个字节。
0xC000000000 xor 0xFFFFFFFF = 0x3FFFFFFF00
再次从上面完成 Xor 和 shift 方法。大约 6 步后,您将获得:
0x13822f2d
然后对上述位序列进行补码。
0x13822f2d xor 0xFFFFFFFF = 0xec7dd0d2
请记住,我们在第一步中颠倒了位顺序以获得以太网线上的表示。现在我们必须扭转这一步,我们终于完成了我们的任务。
0x4b0bbe37
想出这种方法的人应该是...
很多时候你真的想知道你收到的信息是正确的。为了实现这一点,您将收到包含 FCS 的消息并执行与上述相同的步骤 1 到 5。结果应该是他们所说的残留物。这是给定多项式的常数。在这种情况下,它是0xC704DD7B
。
正如mcdowella所提到的,您必须根据您使用的应用程序来玩弄自己的位,直到正确为止。