CRC16 演算法及c實現

2021-06-27 02:27:03 字數 3050 閱讀 5497

標準crc生成多項式如下表:

名稱       生成多項式             簡記式*  標準引用

crc-4       x4+x+1                  3         itu g.704

crc-8       x8+x5+x4+1              0x31                   

crc-8       x8+x2+x1+1              0x07                   

crc-8       x8+x6+x4+x3+x2+x1       0x5e

crc-12      x12+x11+x3+x+1          80f

crc-16      x16+x15+x2+1            8005      ibm sdlc

crc16-ccitt x16+x12+x5+1            1021      iso hdlc, itu x.25, v.34/v.41/v.42, ppp-fcs

crc-32      x32+x26+x23+...+x2+x+1 04c11db7 zip, rar, ieee 802 lan/fddi, ieee 1394, ppp-fcs

crc-32c     x32+x28+x27+...+x8+x6+1 1edc6f41 sctp

生成多項式的最高位固定的1,故在簡記式中忽略最高位1了,如0x1021實際是0x11021。

i、基本演算法(人工筆算):

以crc16-ccitt為例進行說明,crc校驗碼為16位,生成多項式17位。假如資料流為4位元組:byte[3]、byte[2]、byte[1]、byte[0];

資料流左移16位,相當於擴大256×256倍,再除以生成多項式0x11021,做不借位的除法運算(相當於按位異或),所得的餘數就是crc校驗碼。

傳送時的資料流為6位元組:byte[3]、byte[2]、byte[1]、byte[0]、crc[1]、crc[0];

注意:使用長除法進行計算式,需要將除數多項式與預置位0x0000或0xffff異或以後再進行計算。

ii、計算機演算法1(位元型演算法):

1)將擴大後的資料流(6位元組)高16位(byte[3]、byte[2])放入乙個長度為16的暫存器;

2)如果暫存器的首位為1,將暫存器左移1位(暫存器的最低位從下乙個位元組獲得),再與生成多項式的簡記式異或;

否則僅將暫存器左移1位(暫存器的最低位從下乙個位元組獲得);

3)重複第2步,直到資料流(6位元組)全部移入暫存器;

4)暫存器中的值則為crc校驗碼crc[1]、crc[0]。

iii、計算機演算法2(位元組型演算法):256^n表示256的n次方

把按位元組排列的資料流表示成數學多項式,設資料流為byte[n]byte[n-1]byte[n-2]、、、byte[1]byte[0],表示成數學表示式為byte[n]×256^n+byte[n-1]×256^(n-1)

+...+byte[1]*256+byte[0],在這裡+表示為異或運算。設生成多項式為g17(17bit),crc碼為crc16。

則,crc16=(byte[n]×256^n+byte[n-1]×256^(n-1)+...+byte[1]×256+byte[0])×256^2/g17,即資料流左移16位,再除以生成多項式g17。

先變換byte[n-1]、byte[n-1]擴大後的形式,

crc16=byte[n]×256^n×256^2/g17+byte[n-1]×256^(n-1)×256^2/g17+...+byte[1]×256×256^2/g17+byte[0]×256^2/g17

=(z[n]+y[n]/g17)×256^n+byte[n-1]×256^(n-1)×256^2/g17+...+byte[1]×256×256^2/g17+byte[0]×256^2/g17

=z[n]×256^n+×256^(n-1)+...+byte[1]×256×256^2/g17+byte[0]×256^2/g17

=z[n]×256^n+×256^(n-1)+...+byte[1]×256×256^2/g17+byte[0]×256^2/g17

=z[n]×256^n+×256^(n-1)+...+byte[1]×256×256^2/g17+byte[0]×256^2/g17

這樣就推導出,byte[n-1]位元組的crc校驗碼為,即上一位元組crc校驗碼y[n]的高8位(yh8[n])與本位元組byte[n-1]異或,

該結果單獨計算crc校驗碼(即單位元組的16位crc校驗碼,對單位元組可建立**,預先生成對應的16位crc校驗碼),所得的crc校驗碼與上一位元組crc校驗碼y[n]的低8位(yl8[n])

乘以256(即左移8位)異或。然後依次逐個位元組求出crc,直到byte[0]。

位元組型演算法的一般描述為:本位元組的crc碼,等於上一位元組crc碼的低8位左移8位,與上一位元組crc右移8位同本位元組異或後所得的crc碼異或。   

位元組型演算法如下:

1)crc暫存器組初始化為全"0"(0x0000)。(注意:crc暫存器組初始化全為1時,最後crc應取反。)

2)crc暫存器組向左移8位,並儲存到crc暫存器組。

3)原crc暫存器組高8位(右移8位)與資料位元組進行異或運算,得出乙個指向值表的索引。

4)索引所指的錶值與crc暫存器組做異或運算。

5)資料指標加1,如果資料沒有全部處理完,則重複步驟2)。

6)得出crc。

crc ccitt—1,「-1」的意思是crc的初值為0xffff。

方法1:將存有資料的位元組陣列進行逐位計算,求得位元組形式的crc

typedef unsigned __int16    int16u;

#define crc_seed   0xffff   // 該位稱為預置值,使用人工演算法(長除法)時 需要將除數多項式先與該與職位 異或 ,才能得到最後的除數多項式

#define poly16 0x1021  // 該位為簡式書寫 實際為0x11021

int16u crc16(unsigned char *buf,unsigned short length)

;unsigned short crc_ccitt(unsigned char *q, int len)

CRC16校驗演算法實現

迴圈冗餘碼校驗英文名稱為cyclical redundancy check,簡稱crc。它是利用除法及餘數的原理來作錯誤偵測 error detecting 的。實際應用時,傳送裝置計算出crc值並隨資料一同傳送給接收裝置,接收裝置對收到的資料重新計算crc並與收到的crc相比較,若兩個crc值不同...

java實現的CRC16演算法

crc 是先調入一值是全 1 的 16 位暫存器,然後呼叫一過程將訊息中連續的 8 位位元組各當前暫存器中的值進行處理。僅每個字元中的 8bit 資料對 crc 有效,起始位和停止位以及奇偶校驗位均無效。crc 校驗位元組的生成步驟如下 裝乙個 16 位暫存器,所有數字均為 1。取被校驗串的乙個位元...

CRC16 校驗演算法

1 迴圈校驗碼 crc碼 是資料通訊領域中最常用的一種差錯校驗碼,其特徵是資訊字段和校驗欄位的長度可以任意選定。2 生成crc碼的基本原理 任意乙個由二進位制位串組成的 都可以和乙個係數僅為 0 和 1 取值的多項式一一對應。例如 1010111對應的多項式為x6 x4 x2 x 1,而多項式為x5...