2012-02-15 62 views
10

我試圖計算逐個字節的以太網數據包的幀校驗序列(FCS)。多項式爲0x104C11DB7。 我也跟着在這裏看到http://en.wikipedia.org/wiki/Cyclic_redundancy_check或這裏http://www.woodmann.com/fravia/crctut1.htm以太網CRC32計算 - 軟件vs算法結果

的XOR-SHIFT算法假設應該有一個CRC只有一個字節的信息。假設它是0x03。

  1. 步驟:墊32位到右側

    0x0300000000

  2. 對齊多項式,並在與它們的第一比特的左手側是不爲零的數據和XOR它們

    0x300000000 xor 0x209823B6E = 0x109823b6e

  3. 帶餘數對齊再次異或

    0x109823b6e xor 0x104C11DB7 = 0x0d4326d9

由於沒有更多的位左的×03的CRC32應該是0x0d4326d9

不幸的是所有的軟件實現告訴我,我錯了,但我做了什麼錯了還是什麼他們有不同的表現嗎?

Python的告訴我:

"0x%08x" % binascii.crc32(chr(0x03)) 
0x4b0bbe37 

的在線工具,這裏http://www.lammertbies.nl/comm/info/crc-calculation.html#intr得到相同的結果。 我的手計算和上述軟件使用的算法有什麼區別?

UPDATE:

原來有一個類似的問題已經在堆棧溢出:

您發現這裏Python CRC-32 woes

答案雖然這不是很直觀。如果你想它是如何對以太網進行更正式的描述幀,你可以看看Ethernet Standard document 802.3 3部分 - 第二章3.2.9幀校驗序列字段

讓我們繼續從上面的例子:

  1. 顛倒你消息的位順序。這代表他們會逐漸進入接收器的方式。因此

    0x030xC0

  2. 補充第一32位的消息的。注意我們再次用32位填充單個字節。

    0xC000000000 xor 0xFFFFFFFF = 0x3FFFFFFF00

  3. 從上面再次完成XOR和移方法。經過約6步你:然後

    0x13822f2d

  4. 以上位sequense的補充。

    0x13822f2d xor 0xFFFFFFFF = 0xec7dd0d2

  5. 請記住,我們顛倒了位,以獲得在第一步中的以太網線表示。現在我們必須扭轉這一步,最終完成我們的任務。

    0x4b0bbe37

誰用做它應該是這樣過來......

很多時候,你真正想知道您收到的消息是正確的。爲了達到此目的,您需要收到您收到的包含FCS的消息,並執行與上述相同的步驟1至5。結果應該是他們所說的殘渣。對於給定的多項式,這是一個常數。在這種情況下,它是0xC704DD7B

作爲mcdowella提到你必須玩弄你的一些東西,直到你找到正確的,取決於你使用的應用程序。

+1

0x209823B6E從哪裏來? – grieve 2012-02-15 05:31:26

+0

您是否還將初始餘數設置爲0xFFFFFFFF – grieve 2012-02-15 05:48:41

+0

0x209823B6E是多項式的移位版本,以便將其與數據 – sebs 2012-02-15 20:56:14

回答

3

通常需要一些試驗和錯誤才能使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來查找第一個不同的地方,並逐個修正差異。

2

在互聯網上有很多地方你會讀到在計算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. 
+0

「第一位」和「最後一位」是指傳輸順序 - 由於這個原因,它們*不會說「最重要的位」或「最不重要的位」)。 – hobbs 2015-03-06 17:37:08

4

這段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) 

會救我一些時間,如果我發現這個在這裏。