1樓:光輝
crc的本質是模-2除法的餘數,採用的除數不同,crc的型別也就不一樣。通常,crc的除數用生成多項式來表示。 最常用的crc碼及生成多項式名稱生成多項式。
crc-12:
crc-16:
crc-ccitt:
crc-32:
crc校驗實用程式庫 在資料儲存和資料通訊領域,為了保證資料的正確,就不得不採用檢錯的手段。在諸多檢錯手段中,crc是最著名的一種。crc的全稱是迴圈冗餘校驗。
擴充套件資料
通常的crc演算法在計算乙個資料段的crc值時,其crc值是由求解每個數值的crc值的和對crc暫存器的值反覆更新而得到的。這樣,求解crc的速度較慢。通過對crc演算法的研究,我們發現:
乙個8位資料加到16位累加器中去,只有累加器的高8位或低8位與資料相作用,其結果僅有256種可能的組合值。
因而,我們可以用查表法來代替反覆的運算,這也同樣適用於crc32的計算。本文所提供的程式庫中,函式crchware是一般的16位crc的演算法。mk-crctbl用以在記憶體中建立乙個crc數值表。
2樓:
crc 演算法是以 gf(2) 多項式算術為數學基礎的,gf(2) 多項式中只有乙個變數 x ,其係數也只有 0 和 1 ,比如:
1 *x^6 + 0*x^5 + 1*x^4 + 0*x^3 + 0*x^2 +1*x^1 + 1*x^0
= x^6 + x^4 + x + 1
加減運算不考慮進製和退位。說白了就是下面的運算規則:
0 + 0 = 0 0 - 0 = 0
0 + 1 = 1 0 - 1 = 1
1 + 0 = 1 1 - 0 = 1
1 + 1 = 0 1 - 1 = 0
看看這個規則,其實就是乙個異或運算。
每個生成多項式的係數只能是 0 或 1 ,因此我們可以把它轉化為二進位制形式表示, 比如 g(x)=x^4 + x + 1 ,那麼g(x) 對應的二進位制形式就是 10011 , 於是我們就把 gf(2) 多項式的除法轉換成了二進位制形式,和普通除法沒有區別,只是加減運算沒有進製和退位。
比如基於上述規則計算 11010/1001 ,那麼商是 11 ,餘數就是 101 ,簡單吧。
crc 校驗的基本過程
採用 crc 校驗時,傳送方和接收方用同乙個生成多項式 g(x) , g(x) 是乙個 gf(2) 多項式,並且 g(x) 的首位和最後一位的係數必須為 1 。
crc 的處理方法是:傳送方用傳送資料的二進位制多項式 t(x) 除以 g(x) ,得到餘數 y(x) 作為 crc 校驗碼。校驗時,以計算的校正結果是否為 0 為據,判斷資料幀是否出錯。
設生成多項式是 r 階的(最高位是 x^r )具體步驟如下面的描述。
傳送方:
1 )在傳送的 m 位資料的二進位制多項式 t(x) 後新增 r 個 0 ,擴張到 m+ r 位,以容納 r 位的校驗碼,追加 0 後的二進位制多項式為 t(x) ;
2 )用 t(x) 除以生成多項式 g(x) ,得到 r 位的餘數 y(x) ,它就是 crc 校驗碼;
3 )把 y(x) 追加到 t(x) 後面,此時的資料 s(x) 就是包含了 crc 校驗碼的待傳送字串;由於 s(x) = t(x) y(x) ,因此 s(x) 肯定能被 g(x) 除盡。
接收方:
1 )接收資料 n(x) ,這個 n(x) 就是包含了 crc 校驗碼的 m+r 位資料;
2 )計算 n(x) 除以 g(x) ,如果餘數為 0 則表示傳輸過程沒有錯誤,否則表示有錯誤。從 n(x) 去掉尾部的 r 位資料,得到的就是原始資料。
生成多項式可不是隨意選擇的,數學上的東西就免了,以下是一些標準的 crc 演算法的生成多項式:
原始的 crc 校驗演算法
根據多項式除法,我們就可以得到原始的 crc 校驗演算法。假設生成多項式 g(x) 是 r 階的,原始資料存放在 data中,長度為 len 個 bit , reg 是 r+1 位的變數。 以 crc-4 為例,生成多項式 g(x)=x^4 + x + 1 ,對應了乙個 5bits 的二進位制數字 10011 ,那麼 reg 就是 5 bits 。
reg[1] 表明 reg 的最低位, reg[r+1] 是 reg 的最高位。
通過反覆的移位和進行除法,那麼最終該暫存器中的值去掉最高一位就是我們所要求的餘數。所以可以將上述步驟用下面的流程描述:
改進一小步——從 r+1 到 r
由於最後只需要 r 位的餘數,所以我們可以嘗試構造乙個 r 位的 reg ,初值為 0 ,資料 data 依次移入 reg[1] ,同時把reg[r] 移出 reg 。
根據上面的演算法可以知道,只有當移出的資料為 1 時, reg 才和 g(x) 進行 xor 運算;於是可以使用下面的演算法:
3樓:陽光上的橋
資料中拷貝下來的,希望對你有幫助
為了提高編碼效率,在實際運用中大多採用查表法來完成crc-32校驗,下面是產生crc-32校驗嗎的子程式。
unsigned long crc_32_tab[256]=;//事先計算出的參數列,共有256項,未全部列出。
unsigned long generatecrc32(char xdata * databuf,unsigned long len)
crc32=oldcrc32;
return crc32;
}參數列可以先在pc機上算出來,也可在程式初始化時完成。下面是用於計算參數列的c語言子程式,在visual c++ 6.0下編譯通過。
#include
unsigned long int crc32_table[256];
unsigned long int ulpolynomial = 0x04c11db7;
unsigned long int reflect(unsigned long int ref, char ch)
return value;
}init_crc32_table()
crc=crc32_table[i];
crc32_table[i] = reflect(crc32_table[i], 32);}}
4樓:匿名使用者
一篇通俗易懂的關於crc的文章