我试图逐字节计算以太网数据包的帧检查序列(FCS)。多项式为0x104C11DB7。我确实遵循了在这里看到的异或移位算法( 检查或http://www.woodmann.com/fravia/crctut1.htm )。
假设假定有CRC的信息只有一个字节。假设是0x03。
0x03000000000x300000000 xor 0x209823B6E = 0x109823b6e0x109823b6e 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场灾难
虽然这不是很直观。如果您想要对以太网帧进行更正式的描述,可以查看以太网标准文件802.3第3部分--第3.2.9章帧检查序列字段
让我们继续上面的示例:
0x03是0xC00xC000000000 xor 0xFFFFFFFF = 0x3FFFFFFF000x13822f2d0x13822f2d xor 0xFFFFFFFF = 0xec7dd0d20x4b0bbe37不管是谁想出这样的方法应该是..。
很多时候,你真的想知道,你收到的信息是正确的。为了实现这一点,您将接收到的消息,包括FCS,并执行相同的步骤1至5,如上。结果应该是他们所说的残余物。它是给定多项式的常数。在这种情况下,它是0xC704DD7B。
正如mcdowella提到的那样,您必须使用您的比特,直到得到正确的,这取决于您正在使用的应用程序。
发布于 2013-11-18 10:31:47
此片段为以太网编写正确的CRC。
Python 3
# write payload
for byte in data:
f.write(f'{byte:02X}\n')
# write FCS
crc = zlib.crc32(data)
for i in range(4):
byte = (crc >> (8*i)) & 0xFF
f.write(f'{byte:02X}\n')Python 2
# write payload
for byte in data:
f.write('%02X\n' % ord(byte))
# write FCS
crc = zlib.crc32(data) & 0xFFFFFFFF
for i in range(4):
byte = (crc >> (8*i)) & 0xFF
f.write('%02X\n' % byte)如果我在这里找到这个会帮我节省一些时间。
发布于 2012-02-15 06:21:45
要使CRC计算与之匹配,通常需要进行一些尝试和错误,因为您永远不会准确地阅读必须完成的操作。有时你必须对输入字节或多项式进行位反,有时你必须从一个非零值开始,以此类推。
绕过这一问题的一种方法是查看程序的源代码,比如http://sourceforge.net/projects/crcmod/files/ (至少它声称匹配,并为此提供了一个单元测试)。
另一种方法是玩弄实现。例如,如果我在http://www.lammertbies.nl/comm/info/crc-calculation.html#intr上使用计算器,我可以看到给它00000000会产生0x2144DF1C的CRC,但是给它FFFFFFFF会产生FFFFFFFF,所以它并不完全是你描述的多项式除法,对于它,0应该有校验和0。
简单地看一下源代码和这些结果,我认为您需要从0xFFFFFF的CRC开始--但我可能错了,您可能会与实现并行调试代码,使用相应的printfs查找第一个不同之处,并逐个修复差异。
发布于 2013-08-10 20:01:01
在互联网上有很多地方,你会读到,在计算FCS之前,比特顺序必须颠倒,但是802.3规范不是其中之一。引用了2008年版本的规范:
3.2.9 Frame Check Sequence (FCS) field
A cyclic redundancy check (CRC) is used by the transmit and receive algorithms to
generate a CRC value for the FCS field. The FCS field contains a 4-octet (32-bit)
CRC value. This value is computed as a function of the contents of the protected
fields of the MAC frame: the Destination Address, Source Address, Length/ Type
field, MAC Client Data, and Pad (that is, all fields except FCS). The encoding is
defined by the following generating polynomial.
G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11
+ x10 + x8 + x7 + x5 + x4 + x2 + x + 1
Mathematically, the CRC value corresponding to a given MAC frame is defined by
the following procedure:
a) The first 32 bits of the frame are complemented.
b) The n bits of the protected fields are then considered to be the coefficients
of a polynomial M(x) of degree n – 1. (The first bit of the Destination Address
field corresponds to the x(n–1) term and the last bit of the MAC Client Data
field (or Pad field if present) corresponds to the x0 term.)
c) M(x) is multiplied by x32 and divided by G(x), producing a remainder R(x) of
degree ≤ 31.
d) The coefficients of R(x) are considered to be a 32-bit sequence.
e) The bit sequence is complemented and the result is the CRC.
The 32 bits of the CRC value are placed in the FCS field so that the x31 term is
the left-most bit of the first octet, and the x0 term is the right most bit of the
last octet. (The bits of the CRC are thus transmitted in the order x31, x30,...,
x1, x0.) See Hammond, et al. [B37].当然,帧中的其余比特都是按反向顺序传输的,但这并不包括FCS。再说一遍,从规范中:
3.3 Order of bit transmission
Each octet of the MAC frame, with the exception of the FCS, is transmitted least
significant bit first.https://stackoverflow.com/questions/9286631
复制相似问题