CRC演算法詳解(2)

2021-07-03 08:44:45 字數 2481 閱讀 6166

變換到上面的方法後,我們離 table-driven 的方法只有一步之遙了,我們知道乙個位元組能表示的正整數範圍是 0~255,步驟 1 中的計算就是針對 reg 的高 byte 位進行的,於是可以被提取出來,預先計算並儲存到乙個有 256 項的表中,於是下面的演算法就出爐了,這個和上面的演算法本質上並沒有什麼區別。

[cpp]view plain

copy

#define poly 0x04c11db7l // crc32生成多項式

static unsigned 

int crc_table[256];  

unsigned int get_sum_poly(unsigned 

char data)  

return sum_poly;  

}  void create_crc_table()  

}  // 以byte資料為例

unsigned int crc32_3(unsigned 

int data)  

return reg;  

}  

上面的這個演算法已經是乙個table-driven的crc-32演算法了,但是實際上我們看到的crc校驗**都是如下的形式:

[cpp]view plain

copy

r=0;  

while(len--)  

r = (r<<8) ^ t[(r >> 24) ^ *p++];  

下面我們將看看是做了什麼轉化而做到這一點的。

首先上述 crc 演算法中,我們需要為原始資料追加 r/8byte 個 0 , crc-32 就是 4byte 。或者我們可以再計算原始資料之後,把 0 放在後面單獨計算,像這樣:

[cpp]view plain

copy

// 先計算原始資料

for(

int i = 0; i 

// 再計算追加的4byte 0

for(

int i = 0; i 

這看起來已經足夠好了,而事實上我們可以繼續向下進行以免去為了附加的 0 而進行計算。在上面演算法中,最後的 4 次迴圈是為了將輸入資料的最後 r/8 位都移出 reg ,因為 0 對 reg 的值並沒有絲毫影響。

對於 crc-32 ,對於任何輸入資料 dn...d8…d5d4…d1 ,第乙個 for 迴圈將 dn…d8…d5 都依次移入,執行xor 運算再移出 reg ;並將 d4…d1 都移入了 reg ,但是並未移出;因此最後的 4 次迴圈是為了將 d4…d1 都移出 reg 。

di 與 ri 執行 xor 運算後值將會更新,設更新後的值表示為 di』 ,不論執行了多少次 xor 運算。

如果 reg 初始值是 0 ,那麼第乙個 for 迴圈中開始的 4 次迴圈幹的事情就是,把 dn…dn-3 移入到 reg 中(與0 做 xor 結果不變),執行 4 次後 reg 的值就是 dn.dn-1.dn-2.dn-3 ;

第 5 次迴圈的結果就是: reg = crc_table[dn] ^ dn-1.dn-2.dn-3.dn-4 ;

第 6 次迴圈的結果就是: reg = crc_table[dn-1』] ^ dn-2』.dn-3』.dn-4 ; dn 移出 reg 。

因此上面的計算可以分為 3 個階段:

1 )前 4 次迴圈,將 dn.dn-1.dn-2.dn-3 裝入 reg ;

2 )中間的 n-4 次迴圈,依次將 di 移入 reg ,在隨後的 4 次迴圈中,依次計算 di+4 , di+3 , di+2 和 di+1對 di 的影響;最後移出 reg ;  

3 )最後的 4 次迴圈,實際上是為了計算 d4 , d3 , d2 和 d1 都能執行第 2 步的過程;

具體考察 di :

1 ) di 移入到 reg 中, r1=di ,接著與 crc_table[r4] 執行 xor 運算;

2 )迴圈 4 次後, di 成為 reg 的最高位 r4 ,並且因為受到了 dn…di+1 的影響而更新為 di』 ;

上面的運算步驟如下面所示,其中 f 是對應得 crc_table[r] 的值。

可以清晰的看到,最後 reg 的高 byte 是 di 和 f 之間一次次 xor 運算的結果。依然根據 xor 運算的結合律,我們可以分兩步走:

1)  先執行 f 之間的 xor 運算,設結果為 ff ,它就是 reg 的首位元組;

2)  然後再直接將 di 和 ff 進行 xor 運算,並根據結果查 crc 表;

3)  計算出 xor 運算後, di…di-3 已經移入 reg ;因此再將查表結果和 (reg<<8) 執行 xor 運算即可;

這就是方法 2 ,於是我們的 table-driven 的 crc-32 校驗演算法就可以寫成如下的方式了:

[cpp]view plain

copy

reg = 0;  

for(

int i = 0; i 

CRC演算法詳解

1.先舉兩個個例子,使用xor除法 請注意當異或結果首位為0時,除數全部變為0 接下來資料1111後面加上110變成1111110就可以被1001使用異或除法除盡。所以我們想要傳送二進位制資料只要在資料後面加上 除數字數 1 個0,再用除數進行異或除法就可以得到餘數,這個得到的餘數就是crc 對於除...

crc校驗詳解

crc即迴圈冗餘校驗碼 cyclic redundancy check 1 是資料通訊領域中最常用的一種查錯校驗碼,其特徵是資訊字段和校驗欄位的長度可以任意選定。迴圈冗餘檢查 crc 是一種資料傳輸檢錯功能,對資料進行多項式計算,並將得到的結果附在幀的後面,接收裝置也執行類似的演算法,以保證資料傳輸...

CRC校驗和CRC各種演算法

crc校驗和crc各種演算法 1 簡介 crc即 迴圈冗餘校驗碼 cyclic redundancy check 是資料通訊領域中最常用的一種查錯校驗碼,其特徵是資訊字段和校驗欄位的長度可以任意選定。迴圈冗餘檢查 crc 是一種資料傳輸檢錯功能,對資料進行多項式計算,並將得到的結果附在幀的後面,接收...