seb*_*ebs 12 python algorithm crc32 ethernet
我正在尝试逐字节计算以太网数据包的帧校验序列(FCS).多项式是0x104C11DB7.我确实遵循了这里所见的XOR-SHIFT算法http://en.wikipedia.org/wiki/Cyclic_redundancy_check或http://www.woodmann.com/fravia/crctut1.htm
假设假定具有CRC的信息仅为一个字节.假设它是0x03.
步骤:向右打32位
0x0300000000
将多项式和左侧的数据与它们的第一个非零和xor对齐
0x300000000 xor 0x209823B6E = 0x109823b6e
取余数对齐和xor
0x109823b6e xor 0x104C11DB7 = 0x0d4326d9
由于没有剩下的位,0x03的CRC32应该是 0x0d4326d9
不幸的是,所有的软件实现都告诉我我错了,但是我做错了什么或者他们做了什么不同的事情?
Python告诉我:
"0x%08x" % binascii.crc32(chr(0x03))
0x4b0bbe37
Run Code Online (Sandbox Code Playgroud)
这里的在线工具http://www.lammertbies.nl/comm/info/crc-calculation.html#intr获得了相同的结果.我的手计算与上述软件使用的算法有什么区别?
更新:
事实证明堆栈溢出已经存在类似的问题:
你在这里找到一个答案Python CRC-32的问题
虽然这不是很直观.如果您想要更正式地描述如何为以太网帧完成,您可以查看以太网标准文档802.3第3部分 - 第3.2.9章帧校验序列字段
让我们继续上面的例子:
反转邮件的位顺序.这代表了他们逐点进入接收器的方式.
0x03 因此是 0xC0
补充邮件的前32位.请注意,我们再次使用32位填充单个字节.
0xC000000000 xor 0xFFFFFFFF = 0x3FFFFFFF00
再次完成上面的Xor和shift方法.大约6步之后你得到:
0x13822f2d
然后补充上述比特序列.
0x13822f2d xor 0xFFFFFFFF = 0xec7dd0d2
请记住,我们颠倒了位顺序,以便在第一步中获得以太网线上的表示.现在我们必须扭转这一步,我们终于完成了我们的任务.
0x4b0bbe37
想出这种做法的人应该......
很多时候你真的想知道你收到的信息是正确的.为了达到这个目的,您可以收到包括FCS在内的收到的消息,并执行与上述相同的步骤1到5.结果应该是他们所谓的残留物.这是给定多项式的常数.在这种情况下它是0xC704DD7B.
正如mcdowella所提到的那样,你必须玩弄你的位,直到你做对了,这取决于你正在使用的应用程序.
此Python代码段为以太网写入正确的CRC:
# write payload
for byte in data:
f.write('%02X\n' % ord(byte))
# write FCS
crc = zlib.crc32(data)&0xFFFFFFFF
for i in range(4):
b = (crc >> (8*i)) & 0xFF
f.write('%02X\n' % b)
Run Code Online (Sandbox Code Playgroud)
如果我在这里找到这个,本来可以节省我一些时间.
通常需要进行一些尝试和错误才能使 CRC 计算匹配,因为您永远无法准确地阅读必须完成的操作。有时您必须对输入字节或多项式进行位反转,有时您必须从非零值开始,等等。
绕过这个问题的一种方法是查看正确的程序源代码,例如http://sourceforge.net/projects/crcmod/files/(至少它声称匹配,并且附带了一个单元测试) )。
另一个是尝试实施。例如,如果我使用http://www.lammertbies.nl/comm/info/crc-calculation.html#intr上的计算器,我可以看到给它 00000000 会产生 0x2144DF1C 的 CRC,但给它 FFFFFFFF 会产生 FFFFFFFF -所以这不完全是您描述的多项式除法,其中 0 的校验和为 0
快速浏览一下源代码和这些结果,我认为您需要从 0xFFFFFFFF 的 CRC 开始 - 但我可能是错的,您可能最终会与实现并排调试代码,使用相应的 printfs 来找出位置第一个不同,并逐一修复差异。
| 归档时间: |
|
| 查看次数: |
23902 次 |
| 最近记录: |