Ⅰ CRC校驗碼是如何算出來的
問問首頁 問題庫 問問之星| 問問團隊 全部問題 >教育/科學>理工科>問題頁 「我的問問 我的2009」活動獎品發放通知! 已解決問題 收藏 轉載到QQ空間 假設CRC的生成多項式G(x)=x3+x+1轉換成對應的2進制除數1011是如何轉換成二進制的 [ 標簽:crc 多項式,crc,二進制 ] 假設CRC的生成多項式G(x)=x3+x+1,信息碼為11001校驗碼孝瞎橋是多少,碼字多少是CRC錯誤。 /wx夢想 回答:1 人氣:1 解決時間:2009-04-29 18:27 滿意答案在串列傳送(磁碟、通訊)中,廣泛採用循環巧猛冗餘校驗碼(CRC)。CRC也是給信息碼加上幾位校驗碼,以增加整個編碼系統的碼距和查錯糾錯能力。 CRC的理論很復雜,一般書上只介紹已有生成多項式後計算校驗碼的方法。檢錯能力與生成多項式有關,只能根據書上的結論死記。 循環冗餘校驗碼(CRC)的基本原理是:在K位信息碼後再拼接R位的校驗碼,整個編碼長度為N位,因此,這種編碼又叫(N,K)碼。對於一個給定的(N,K)碼,可以證明存在一個最高次冪為N-K=R的多項式G(x)。根據G(x)可以生成K位信息的校驗碼,而G(x)叫做這個CRC碼的生成多項神塵式。 校驗碼的具體生成過程為:假設發送信息用信息多項式C(X)表示,將C(x)左移R位,則可表示成C(x)*2R,這樣C(x)的右邊就會空出R位,這就是校驗碼的位置。通過C(x)*2R除以生成多項式G(x)得到的余數就是校驗碼。 幾個基本概念 1、多項式與二進制數碼 多項式和二進制數有直接對應關系:x的最高冪次對應二進制數的最高位,以下各位對應多項式的各冪次,有此冪次項對應1,無此冪次項對應0。可以看出:x的最高冪次為R,轉換成對應的二進制數有R+1位。 多項式包括生成多項式G(x)和信息多項式C(x)。 如生成多項式為G(x)=x4+x3+x+1, 可轉換為二進制數碼11011。 而發送信息位 1111,可轉換為數據多項式為C(x)=x3+x2+x+1。 2、生成多項式 是接受方和發送方的一個約定,也就是一個二進制數,在整個傳輸過程中,這個數始終保持不變。 在發送方,利用生成多項式對信息多項式做模2除生成校驗碼。在接受方利用生成多項式對收到的編碼多項式做模2除檢測和確定錯誤位置。 應滿足以下條件: a、生成多項式的最高位和最低位必須為1。 b、當被傳送信息(CRC碼)任何一位發生錯誤時,被生成多項式做模2除後應該使余數不為0。 c、不同位發生錯誤時,應該使余數不同。 d、對余數繼續做模2除,應使余數循環
Ⅱ C語言實現CRC校驗
把我知道的說一下:
碼流後面加8個0可以用移位得到(碼流<<8;)
單次異或運算可以用運算符:^(運算符兩邊為常數)
由於你校驗的是5個位元組,且要多次異或運算,所以得藉助數組,或其它的數據結果才能完成。
最後問一下你是做硬體的嗎
Ⅲ crc校驗碼計算方法
已知信息位為1100,生成多項式G(x) = x3+x+1,求CRC碼。
M(x) = 1100 M(x)*x3 = 1100000 G(x) = 1011
M(x)*x3 / G(x) = 1110 + 010 /1011 R(x) = 010
CRC碼為: M(x)*x 3+R(x)=1100000+010 =1100010
其原理是:CRC碼一般在k位信息位之後拼接r位校驗位生成。編碼步驟如下:
(1)將待編碼的k位信息灶橘高表示成多項式 M(x)。
(2)伍襲將 M(x)左移 r 位,得到 M(x)*xr 。
(3)用r+1位的生成多項式G(x)去除M(x)*xr 得到余數R(x)。
(4)將M(x)*xr 與R(x)作模2加,得到CRC碼。
(3)crc校驗演算法代碼擴展閱讀:
CRC校驗碼計算詳解:採用CRC進行差錯檢驗,生成多項式為G(X)=X4+X+1,信息碼字為10110,則計算出的CRC校驗碼是:A. 0000 B. 0100 C. 0010 D.1111
符號表示假定:多項式和多項式的系數排列均用相同的符號表示,如
G(X)= X4+X+1
G(X)=10011
已知條件如下:
原碼字記做M(X),即:M(X) = 10110
生成多項式記做G(X),即:G(X) = 10011
G(X)的最高階隱尺數記做r,此處r = 4
Ⅳ CRC校驗的演算法
在代數編碼理論中,將一個碼組表示為一個多項式,碼組中各碼元當作多項式的系數。例如 1100101 表示為1·x6+1·x5+0·x4+0·x3+1·x2+0·x+1,即 x6+x5+x2+1。
設編碼前的原始信息多項式為P(x),P(x)的最高冪次加1等於k;生成多項式為G(x),G(x)的最高冪次等於r;CRC多項式為R(x);編碼後的帶CRC的信息多項式為T(x)。
發送方編碼方法:將P(x)乘以xr(即對應的二進制碼序列左移r位),再除以G(x),所得余式即為R(x)。用公式表示為T(x)=xrP(x)+R(x)
接收方解碼方法:將T(x)除以G(x),得到一個數,如果這個余數為0,則說明傳輸中無錯誤發生,否則說明傳輸有誤。
舉例來說,設信息編碼為1100,生成多項式為1011,即P(x)=x3+x2,G(x)=x3+x+1,計算CRC的過程為
xrP(x) =x3(x3+x2) = x6+x5 G(x)= x3+x+1 即 R(x)=x。注意到G(x)最高冪次r=3,得出CRC為010。
如果用豎式除法(計算機的模二,計算過程為
1110 ------- 1011 /1100000 (1100左移3位) 1011 ---- 1110 1011 ----- 1010 1011 ----- 0010 0000 ---- 010 因此,T(x)=(x6+x5)+(x)=x6+x5+x, 即 1100000+010=1100010
如果傳輸無誤,
T(x)= (x6+x5+x)/G(x) = , G(x)= 無余式。回頭看一下上面的豎式除法,如果被除數是1100010,顯然在商第三個1時,就能除盡。
上述推算過程,有助於我們理解CRC的概念。但直接編程來實現上面的演算法,不僅繁瑣,效率也不高。實際上在工程中不會直接這樣去計算和驗證CRC。
下表中列出了一些見於標準的CRC資料:
名稱 生成多項式 簡記式* 應用舉例
CRC-4 x4+x+1 3 ITU G.704
CRC-8 x8+x5+x4+1 31 DS18B20
CRC-12 x12+x11+x3+x2+x+1 80F
CRC-16 x16+x15+x2+1 8005 IBM SDLC
CRC-ITU** x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS,ZigBee
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統一去掉了,如04C11DB7實際上是104C11DB7。 ** 前稱CRC-CCITT。ITU的前身是CCITT。
備註:
(1)生成多項式是標准規定的
(2)CRC校驗碼是基於將位串看作是系數為0或1的多項式,一個k位的數據流可以看作是關於x的從k-1階到0階的k-1次多項式的系數序列。採用此編碼,發送方和接收方必須事先商定一個生成多項式G(x),其高位和低位必須是1。要計算m位的幀M(x)的校驗和,基本思想是將校驗和加在幀的末尾,使這個帶校驗和的幀的多項式能被G(x)除盡。當接收方收到加有校驗和的幀時,用G(x)去除它,如果有餘數,則CRC校驗錯誤,只有沒有餘數的校驗才是正確的。
Ⅳ CRC16校驗碼如何計算
首先G(X)=X3+X+1可以得出G(x)=1011[G(x)中的1就是二進制第0位為1,X就是第一位為1,沒有X^2,所以第二位為0,X^3則第三位為1。所以就是1011]
M(x)=0011M(x)*x3=0011000
M(x)*x3/G(x)的余數是101所以R(X)=101
CRC碼為:M(x)*x3+R(x)=0011000+010=0011010
在計算機網路通信中
運用CRC校驗時相對於其他校驗方法就有一定的優勢。CRC可以高比例的糾正信息傳輸過程中的錯誤,可以在極短的時間內完成數據校驗碼的計算,並迅速完成糾錯過程,通過數據包自動重發的方式使得計算機的通信速度大幅提高,對通信效率和安全提供了保障。由於CRC演算法檢驗的檢錯能力極強,且檢測成本較低,因此在對於編碼器和電路的檢測中使用較為廣泛。
以上內容參考:網路-CRC
Ⅵ 求modbus 通訊 crc校驗代碼
CRC是先調入一值是全「1」的16位寄存器,然後調用一過程將消息中連續的8位位元組各當前寄存器中的值進行
處理。僅每個字元中的8Bit數據對CRC有效,起始位和停止位以及奇偶校驗位均無效。
CRC產生過程中,每個8位字元都單獨和寄存器內容相或(OR),結果向最低有效位方向移動,最高有效位以0
填充。LSB被提取出來檢測,如果LSB為1,寄存器單獨和預置的值或一下,如果LSB為0,則不進行。整個過程要重
復8次。在最後一位(第8位)完成後,下一個8位位元組又單獨和寄存器的當前值相或。最銷稿終寄存器中的值,是消息
中所有的位元組都執行之後的CRC值。 CRC添加到消息中時,低位元組先加入,然後高位元組。
CRC簡單函數歷敏如下:
unsigned short CRC16(puchMsg,usDataLen)
unsigned char *puchMsg; /* 要進行CRC校驗的消息 */
unsigned short usDataLen; /* 消息中位元組數 */
{
unsigned char uchCRCHi=0xFF; /* 高CRC位元組初始化 */
unsigned char uchCRCLo=0xFF; /* 低CRC 位元組初始化 */
unsigned uIndex; /* CRC循虧爛孝環中的索引 */
while (usDataLen--) /* 傳輸消息緩沖區 */
{
uIndex=uchCRCHi^*puchMsgg++; /* 計算CRC */
uchCRCHi=uchCRCLo^auchCRCHi[uIndex];
uchCRCLo=auchCRCLo[uIndex];
}
return (uchCRCHi<<8|uchCRCLo);
}
/* CRC 高位位元組值表 */
static unsigned char auchCRCHi[]={
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};
/* CRC低位位元組值表*/
static char auchCRCLo[]={
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};
好好看看吧不會連這么簡單的C++語言都讀不懂吧???
Ⅶ crc16校驗的c語言程序
下面我們以CRC-16為例來說明任意長度數據流的CRC校驗碼生成過程。我們採用將數據流分成若干個8bit字元,並由低位元組到高位元組傳送的並行方法來求CRC校驗碼。具體計算過程為:用一個16bit的寄存器來存放CRC校驗值,且設定其初值為0x0000;將數據流的第一個8bit與16bit的CRC寄存器的高位元組相異或,並將結果存入CRC寄存器高位元組;CRC寄存器左移一位,最低1bit補零,同時檢查移出的最高1bit,若移出的最高1bit為0,則繼續按上述過程左移,若最高1bit為1,則將CRC寄存器中的值與生成多項式碼相異或,結果存入CRC寄存器值;繼續左移並重復上述處理方法,直到將8bit數據處理完為止,則此時CRC寄存器中的值就是第一個8bit數據對應的CRC校驗碼;然後將此時CRC寄存器的值作為初值,用同樣的處理方法重復上述步驟來處理下一個8bit數據流,直到將所有的8bit字元都處理完後,此刻CRC寄存器中的值即為整個數據流對應的CRC校驗碼。
下面示出了其計算過程的流程圖:
在用C語言編寫CRC校驗碼的實現程序時我們應該注意,生成多項式 對應的十六進制數為0x18005,由於CRC寄存器左移過程中,移出的最高位為1時與 相異或,所以與16bit的CRC寄存器對應的生成多項式的十六進制數可用0x8005表示。下面給出並行處理8bit數據流的C源程序:
unsigned short crc_dsp(unsigned short reg, unsigned char data_crc)
//reg為crc寄存器, data_crc為將要處理的8bit數據流
{
unsigned short msb; //crc寄存器將移出的最高1bit
unsigned short data;
unsigned short gx = 0x8005, i = 0; //i為左移次數, gx為生成多項式
data = (unsigned short)data_crc;
data = data << 8;
reg = reg ^ data;
do
{
msb = reg & 0x8000;
reg = reg << 1;
if(msb == 0x8000)
{
reg = reg ^ gx;
}
i++;
}
while(i < 8);
return (reg);
}
以上為處理每一個8bit數據流的子程序,在計算整個數據流的CRC校驗碼時,我們只需將CRC_reg的初值置為0x0000,求第一個8bit的CRC值,之後,即可將上次求得的CRC值和本次將要處理的8bit數據作為函數實參傳遞給上述子程序的形參進行處理即可,最終返回的reg值便是我們所想得到的整個數據流的CRC校驗值。
Ⅷ 高分求計算CRC校驗碼的C語言程序
你就是想要CRC8-CCITT的代碼,這個到處都是。
http://www.rajivchakravorty.com/source-code/uncertainty/multimedia-sim/html/crc8_8c-source.html
我一直有CRC16,沒試過這個,但應該差不多。
參考文獻:http://blog.sina.com.cn/s/blog_5e330a280100fcp9.html
Ⅸ CRC碼的計算方法
給信息碼補5個0,然後去除多項式,余數就是較驗碼
Ⅹ 計算CRC校驗碼問題
.版本
2
.子程序
模塊_求CRC校驗碼,
,
公開
.參數
要校驗的位元組組,
位元組型,
數組
.參數
要校驗的位元組個數,
整數型
.參數
返回CRC碼高位,
位元組型,
參考
.參數
返回CRC碼低位,
位元組型,
參考
.局部變數
循環計數2,
整數型
.局部變數
循環計數1,
整數型
.局部變數
CRC高位,
位元組型
.局部變數
CRC低位,
位元組型
.局部變數
多項式高位,
位元組型
.局部變數
多項式低位,
位元組型
.局部變數
保存字高位,
位元組型
.局部變數
保存字低位,
位元組型
CRC高位
=
255
CRC低位
=
255
多項式高位
=
160
多項式低位
=
1
.判斷循環首
(循環計數1
<
要校驗的字罩巧節個數)
CRC低位
=
位異或
(CRC低位,
要校驗的位元組組
[循環計數1
+
1])
循環計數2
=
0
.判斷循環物斗鍵首
(循環計數2
<
8)
保存字高位
=
CRC高位
保存字低位
=
CRC低位
CRC高位
=
CRC高位
÷
2
CRC低位
=
CRC低位
÷
2
.如果真
(位與
(保存字高位,
1)
=
1)
CRC低位銷森
=
位或
(CRC低位,
128)
.如果真結束
.如果真
(位與
(保存字低位,
1)
=
1)
CRC高位
=
位異或
(CRC高位,
多項式高位)
CRC低位
=
位異或
(CRC低位,
多項式低位)
.如果真結束
循環計數2
=
循環計數2
+
1
.判斷循環尾
()
循環計數1
=
循環計數1
+
1
.判斷循環尾
()
返回CRC碼高位
=
CRC高位
返回CRC碼低位
=
CRC低位
返回
()
以上是我用E語言做的CRC校驗程序,研究了5天
才做出來的,提供給大家