變換到上面的方法後,我們離 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 是一種資料傳輸檢錯功能,對資料進行多項式計算,並將得到的結果附在幀的後面,接收...