2023-03-06文化32位crc在線計算
大家好,小編來為大家解答以下問題,32位crc在線計算,crc32在線計算,今天讓我們一起來看看吧!
為了提高編碼效率,在實際運用中大多采用查表法來完成CRC-32校驗,下面是產生CRC-32校驗嗎的子程序。
unsigned long crc_32_tab[256]={ 。
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,0x0edb8832,…, 0x5a05df1b, 0x2d02ef8d 。
};//事先計算出的參數表,共有256項,未全部列出。
unsigned long GenerateCRC32(char xdata * DataBuf,unsigned long len) 。
{
unsigned long oldcrc32; 。
unsigned long crc32; 。
unsigned long oldcrc; 。
unsigned int charcnt; 。
char c,t;
oldcrc32 = 0x00000000; //初值為0 。
charcnt=0;
while (len--) { 。
t= (oldcrc32 >> 24) & 0xFF; //要移出的字節的值 。
oldcrc=crc_32_tab[t]; //根據移出的字節的值查表 。
c=DataBuf[charcnt]; //新移進來的字節值 。
oldcrc32= (oldcrc32 << 8) | c; //將新移進來的字節值添在寄存器末字節中 。
oldcrc32=oldcrc32^oldcrc; //將寄存器與查出的值進行xor運算 。
charcnt++;
}
crc32=oldcrc32; 。
return crc32;
}
參數表可以先在PC機上算出來,也可在程序初始化時完成。下面是用于計算參數表的c語言子程序,在Visual C++ 6.0下編譯通過。
#include <stdio.h> 。
unsigned long int crc32_table[256]; 。
unsigned long int ulPolynomial = 0x04c11db7; 。
unsigned long int Reflect(unsigned long int ref, char ch) 。
{ unsigned long int value(0); 。
// 交換bit0和bit7,bit1和bit6,類推 。
for(int i = 1; i < (ch + 1); i++) 。
{ if(ref & 1) 。
value |= 1 << (ch - i); 。
ref >>= 1; } 。
return value;
}
init_crc32_table() 。
{ unsigned long int crc,temp; 。
// 256個值
for(int i = 0; i <= 0xFF; i++) 。
{ temp=Reflect(i, 8); 。
crc32_table[i]= temp<< 24; 。
for (int j = 0; j < 8; j++){ 。
unsigned long int t1,t2; 。
unsigned long int flag=crc32_table[i]&0x80000000; 。
t1=(crc32_table[i] << 1); 。
if(flag==0)
t2=0;
else
t2=ulPolynomial; 。
crc32_table[i] =t1^t2 ; } 。
crc=crc32_table[i]; 。
crc32_table[i] = Reflect(crc32_table[i], 32); 。
}
您好,對于你的遇到的問題,我很高興能為你提供幫助,我之前也遇到過喲,以下是我的個人看法,希望能幫助到你,若有錯誤,還望見諒!。展開全部。
CRC的本質是模-2除法的余數,采用的除數不同,CRC的類型也就不一樣。通常,CRC的除數用生成多項式來表示。 最常用的CRC碼及生成多項式名稱生成多項式。
CRC-12:
CRC-16:
CRC-CCITT:
CRC-32:
CRC校驗實用程序庫 在數據存儲和數據通訊領域,為了保證數據的正確,就不得不采用檢錯的手段。在諸多檢錯手段中,CRC是最著名的一種。CRC的全稱是循環冗余校驗。非常感謝您的耐心觀看,如有幫助請采納,祝生活愉快!謝謝!
數據結構算法:CRC32算法實現原理。
簡而言之,CRC是一個數值。該數值被用于校驗數據的正確性。CRC數值簡單地說就是通過讓你需要做處理的數據除以一個常數而得到的余數。當你得到這個數值后你可以將這個數值附加到你的數據后,當數據被傳送到其他地方后,取出原始數據(可能在傳送過程中被破壞)與附加的CRC數值,然后將這里的原始數據除以之前那個常數(約定好的)然后得到新的CRC值。比較兩個CRC值是否相等即可確認你的數據是否在傳送過程中出現錯誤。
那么,如何讓你的數據除以一個常數?方法是對你的數據進行必要的編碼處理,逐字節處理成數字。
那么這個常數是什么?你不必關注它是什么,也不需要關注它是如何獲得的。當你真的要動手寫一個CRC的實現算法時,我可以告訴你,CRC的理論學家會告訴你。不同長度的常數對應著不同的CRC實現算法。當這個常數為32位時,也就是這里所說的CRC32。
以上內容你不必全部理解,因為你需要查閱其他資料來獲取CRC完整的理論介紹。
The mathematics behind CRC ?。
很多教科書會把CRC與多項式關聯起來。這里的多項式指的是系數為0或1的式子,例如:a0 + a1*x + a2*x^2 + ... + an*x^n。其中a0, a1, ..., an要么為0要么為1。我們并不關注x取什么值。
(如果你要關注,你可以簡單地認為x為2) 這里把a0, a1, ..., an的值取出來排列起來,就可以表示比特流。例如 1 + x + x^3所表示的比特流就為:1101。部分資料會將這個順序顛倒,這個很正常。
什么是生成多項式?
所謂的生成多項式,就是上面我所說的常數。注意,在這里,一個多項式就表示了一個比特流,也就是一堆1、0,組合起來最終就是一個數值。例如CRC32算法中,這個生成多項式為:c(x) = 1 + x + x^2 + x^4 + x^5 + x^7 + x^8 + x^10 + x^11 + x^12 + x^16 + x^22 + x^23 + x^26 + x^32。其對應的數字就為:11101101101110001000001100100000(x^32在實際計算時隱含給出,因此這里沒有包含它的系數),也就是0xEDB88320(多項式對應的數字可能顛倒,顛倒后得到的是0x04C11DB7,其實也是正確的)。
由此可以看出,CRC值也可以看成我們的數據除以一個生成多項式而得到的余數。
如何做這個除法?
套用大部分教科書給出的計算方法,因為任何數據都可以被處理成純數字,因此,在某種程度上說,我們可以直接開始這個除法。盡管事實上這并不是標準的除法。例如,我們的數據為1101011011(方便起見我直接給二進制表示了,從這里也可以看出,CRC是按bit進行計算的),給定的生成多項式(對應的值)為10011。通常的教科書會告訴我們在進行這個除法前,會把我們的數據左移幾位(生成多項式位數-1位),從而可以容納將來計算得到的CRC值(我上面所說的將CRC值附加到原始數據后)。但是為什么要這樣做?我也不知道。(不知道的東西不能含糊過)那么,除法就為:
1100001010
_______________。
10011 ) 11010110110000 附加了幾個零的新數據。
10011......... 這里的減法(希望你不至于忘掉小學算術)是一個異或操作。
-----.........。
10011........。
10011........。
-----........。
00001....... 逐bit計算。
00000.......
-----.......
00010......
00000......
-----......
00101.....
00000.....
-----.....
01011....
00000....
-----....
10110...
10011...
-----...
01010..
00000..
-----..
10100.
10011.
-----.
01110
00000
-----
1110 = 這個余數也就是所謂的CRC值,通常又被稱為校驗值。
希望進行到這里,你可以獲取更多關于CRC的感性認識。而我們所要做的,也就是實現一個CRC的計算算法。說白了,就是提供一個程序,給定一段數據,以及一個生成多項式(對于CRC32算法而言該值固定),然后計算得出上面的1110余數。
循環冗余校驗碼的計算方法:
編碼原理:
現假設有:有效信息:M;
除數G(生成多項式)有:M/G=Q+R/G;
此時,可選擇R作為校驗位,則MR即為校驗碼。
校驗原理:(M-R)/G=Q+0/G。
說明:以接收到的校驗碼除以約定的除數,若余數為0,則可認為接收到的數據是正確的。
例:有效信息1101,生成多項式樣1011。
循環校驗碼解:
有效信息1101(k=4),即M(x)=x3+x2+x0,生成多項式1011(r+1=4,即r=3);
即G(x)=x3+x1+x0,M(x)·x3=x6+x5+x3,即1101000(對1101左移三位);
M(x)·x3/G(x)=1101000/1011=1111+001/1011????即1010的CRC是:1101001?。
計算圖文如下?:
CRC(Cyclic Redundancy Check)循環冗余校驗碼,是常用的校驗碼,在早期的通信中運用廣泛,因為早期的通信技術不夠可靠(不可靠性的來源是通信技術決定的,比如電磁波通信時受雷電等因素的影響),不可靠的通信就會帶來‘確認信息’的困惑,書上提到紅軍和藍軍通信聯合進攻山下的敵軍的例子,第一天紅軍發了條信息要藍軍第二天一起進攻,藍軍收到之后,發一條確認信息,但是藍軍擔心的是‘確認信息’如果也不可靠而沒有成功到達紅軍那里,那自己不是很危險?于是紅軍再發一條‘對確認的確認信息’,但同樣的問題還是不能解決,紅軍仍然不敢貿然行動。
一、生成多項式不同:
1、crc16的生成多項式為:X16+X15+X2+1。
2、crc32的生成多項式為:X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1。
二、表示法不同:
1、crc16的的表示法為:0X18005,其對應校驗二進制位列為1 1000 0000 0000 0101。
2、crc32的表示法為:0x104C11DB7,CRC32的生成項是: 1 0000 0100 1100 0001 0001 1101 1011 0111? (33個比特) ,顛倒過來,就可以寫成1110 1101 1011 1000 1000 0011 0010 0000 1 一般生成項簡寫時不寫最高位的1,故生成項是0x04C11DB7,顛倒后的生成項是0xEDB88320。
CRC32的生成項是33比特,最高位是消掉的,即CRC值是32比特(4個字節),即寬度W=32,就是說,在計算前,原始數據后面要先擴展W=32個比特0,即4個0x00字節。
三、應用不同:
1、crc16應用在 按位計算:程序空間十分苛刻但 CRC 計算速度要求不高的微控制器系統按字節計算:程序空間較大且 CRC 計算速度要求較高的計算機或微控制器系統,半字節計算:程序空間不太大,且 CRC 計算速度又不可以太慢的微控制器系統。
2、crc32應用在 ZIP, RAR,IEEE 802 LAN/FDDI,IEEE 1394,PPP-FCS。
參考資料來源:百度百科-CRC32。
參考資料來源:百度百科-CRC。
天哪,我的老伙計,你想知道為什么要轉成int,
真是見鬼,其實我也不太了解。
看在上帝的份兒上,我們為什么不坐下喝杯咖啡呢。
哦,我是說,你看這個函數的返回類型是int,
還有什么會比返回UInt32的時候編譯器報錯更令人煩躁的呢?
循環冗余檢驗 (CRC) 算法原理。
轉載:http://www.cnblogs.com/esestt/archive/2007/08/09/848856.html。
Cyclic Redundancy Check循環冗余檢驗,是基于數據計算一組效驗碼,用于核對數據傳輸過程中是否被更改或傳輸錯誤。
算法原理
假設數據傳輸過程中需要發送15位的二進制信息 g=101001110100001,這串二進制碼可表示為代數多項式g(x) = x^14 + x^12 + x^9 + x^8 + x^7 + x^5 + 1,其中g中第k位的值,對應g(x)中x^k的系數。將g(x)乘以x^m,既將g后加m個0,然后除以m階多項式h(x),得到的(m-1)階余項 r(x)對應的二進制碼r就是CRC編碼。
h(x)可以自由選擇或者使用國際通行標準,一般按照h(x)的階數m,將CRC算法稱為CRC-m,比如CRC-32、CRC-64等。國際通行標準可以參看http://en.wikipedia.org/wiki/Cyclic_redundancy_check。
g(x)和h(x)的除運算,可以通過g和h做xor(異或)運算。比如將11001與10101做xor運算:
明白了xor運算法則后,舉一個例子使用CRC-8算法求101001110100001的效驗碼。CRC-8標準的h(x) = x^8 + x^7 + x^6 + x^4 + x^2 + 1,既h是9位的二進制串111010101。
經過迭代運算后,最終得到的r是10001100,這就是CRC效驗碼。
通過示例,可以發現一些規律,依據這些規律調整算法:
1. 每次迭代,根據gk的首位決定b,b是與gk進行運算的二進制碼。若gk的首位是1,則b=h;若gk的首位是0,則b=0,或者跳過此次迭代,上面的例子中就是碰到0后直接跳到后面的非零位。
2. 每次迭代,gk的首位將會被移出,所以只需考慮第2位后計算即可。這樣就可以舍棄h的首位,將b取h的后m位。比如CRC-8的h是111010101,b只需是11010101。
3. 每次迭代,受到影響的是gk的前m位,所以構建一個m位的寄存器S,此寄存器儲存gk的前m位。每次迭代計算前先將S的首位拋棄,將寄存器左移一位,同時將g的后一位加入寄存器。若使用此種方法,計算步驟如下:
※藍色表示寄存器S的首位,是需要移出的,b根據S的首位選擇0或者h。黃色是需要移入寄存器的位。S'是經過位移后的S。
查表法
同樣是上面的那個例子,將數據按每4位組成1個block,這樣g就被分成6個block。
下面的表展示了4次迭代計算步驟,灰色背景的位是保存在寄存器中的。
經4次迭代,B1被移出寄存器。被移出的部分,不我們關心的,我們關心的是這4次迭代對B2和B3產生了什么影響。注意表中紅色的部分,先作如下定義:
B23 = 00111010
b1 = 00000000
b2 = 01010100
b3 = 10101010
b4 = 11010101
b' = b1 xor b2 xor b3 xor b4。
4次迭代對B2和B3來說,實際上就是讓它們與b1,b2,b3,b4做了xor計算,既:
B23 xor b1 xor b2 xor b3 xor b4。
可以證明xor運算滿足交換律和結合律,于是:
B23 xor b1 xor b2 xor b3 xor b4 = B23 xor (b1 xor b2 xor b3 xor b4) = B23 xor b'。
b1是由B1的第1位決定的,b2是由B1迭代1次后的第2位決定(既是由B1的第1和第2位決定),同理,b3和b4都是由B1決定。通過B1就 可以計算出b'。另外,B1由4位組成,其一共2^4有種可能值。于是我們就可以想到一種更快捷的算法,事先將b'所有可能的值,16個值可以看成一個 表;這樣就可以不必進行那4次迭代,而是用B1查表得到b'值,將B1移出,B3移入,與b'計算,然后是下一次迭代。
可看到每次迭代,寄存器中的數據以4位為單位移入和移出,關鍵是通過寄存器前4位查表獲得。
,這樣的算法可以大大提高運算速度。
上面的方法是半字節查表法,另外還有單字節和雙字節查表法,原理都是一樣的——事先計算出2^8或2^16個b'的可能值,迭代中使用寄存器前8位或16位查表獲得b'。
PS:補充重要知識點:
http://hi.baidu.com/ivan_liumh/blog/item/0fd28dd3c63062d9562c8479.html。
循環冗余校驗碼
在串行傳送(磁盤、通訊)中,廣泛采用循環冗余校驗碼(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除,應使余數循環。
將這些要求反映為數學關系是比較復雜的。但可以從有關資料查到常用的對應于不同碼制的生成多項式如圖9所示:
圖9 常用的生成多項式
3、模2除(按位除)
模2除做法與算術除法類似,但每一位除(減)的結果不影響其它位,即不向上一位借位。所以實際上就是異或。然后再移位移位做下一位的模2減。步驟如下:
a、用除數對被除數最高幾位做模2減,沒有借位。
b、除數右移一位,若余數最高位為1,商為1,并對余數做模2減。若余數最高位為0,商為0,除數繼續右移一位。
c、一直做到余數的位數小于除數時,該余數就是最終余數。
【例】1111000除以1101:
1011———商
————
1111000-----被除數。
1101———— 除數
————
010000
1101
————
01010
1101
————
111————余數
CRC碼的生成步驟
1、將x的最高冪次為R的生成多項式G(x)轉換成對應的R+1位二進制數。
2、將信息碼左移R位,相當與對應的信息多項式C(x)*2R。
3、用生成多項式(二進制數)對信息碼做模2除,得到R位的余數。
4、將余數拼到信息碼左移后空出的位置,得到完整的CRC碼。
【例】假設使用的生成多項式是G(x)=x3+x+1。4位的原始報文為1010,求編碼后的報文。
解:
1、將生成多項式G(x)=x3+x+1轉換成對應的二進制除數1011。
2、此題生成多項式有4位(R+1),要把原始報文C(x)左移3(R)位變成1010000。
3、用生成多項式對應的二進制數對左移4位后的原始報文進行模2除:
1001-------商
------------------------。
1010000
1011----------除數。
------------
1000
1011
------------
011-------余數(校驗位)
5、編碼后的報文(CRC碼):
1010000
+ 011。
------------------。
1010011
CRC的和糾錯
在 接收端收到了CRC碼后用生成多項式為G(x)去做模2除,若得到余數為0,則碼字無誤。若如果有一位出錯,則余數不為0,而且不同位出錯,其余數也不 同。可以證明,余數與出錯位的對應關系只與碼制及生成多項式有關,而與待測碼字(信息位)無關。圖10給出了G(x)=1011,C(x)=1010的出 錯模式,改變C(x)(碼字),只會改變表中碼字內容,不改變余數與出錯位的對應關系。
圖10 (7,4)CRC碼的出錯模式(G(x)=1011)
如 果循環碼有一位出錯,用G(x)作模2除將得到一個不為0的余數。如果對余數補0繼續除下去,我們將發現一個有趣的結果;各次余數將按圖10順序循環。例 如第一位出錯,余數將為001,補0后再除(補0后若最高位為1,則用除數做模2減取余;若最高位為0,則其最低3位就是余數),得到第二次余數為 010。以后繼續補0作模2除,依次得到余數為100,0ll…,反復循環,這就是“循環碼”名稱的由來。這是一個有價值的特點。如果我們在求出余數不為 0后,一邊對余數補0繼續做模2除,同時讓被檢測的校驗碼字循環左移。圖10說明,當出現余數(101)時,出錯位也移到A7位置。可通過異或門將它糾正后在下一次移位時送回A1。這樣我們就不必像海明校驗那樣用譯碼電路對每一位提供糾正條件。當位數增多時,循環碼校驗能有效地降低硬件代價,這是它得以廣泛應用的主要原因。
【例】 對圖10的CRC碼(G(x)=1011,C(x)=1010),若接收端收到的碼字為1010111,用G(x)=1011做模2除得到一個不為0的余 數100,說明傳輸有錯。將此余數繼續補0用G(x)=1011作模2除,同時讓碼字循環左移1010111。做了4次后,得到余數為101,這時碼字也 循環左移4位,變成1111010。說明出錯位已移到最高位A7,將最高位1取反后變成0111010。再將它循環左移3位,補足7次,出錯位回到A3位,就成為一個正確的碼字1010011。
引用:http://hi.baidu.com/tudou888/blog/item/36df6017172a6e4020a4e95c.html。
CRC-32 的程序實現
為了提高編碼效率,在實際運用中大多采用查表法來完成CRC-32 校驗,下面是產生CRC-32 。
校驗嗎的子程序。
unsigned long crc_32_tab[256]={ 。
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 。
0x9e6495a3,0x0edb8832,…, 0x5a05df1b, 0x2d02ef8d 。
};//事先計算出的參數表,共有256 項,未全部列出。
unsigned long GenerateCRC32(char xdata * DataBuf,unsigned long len) 。
{
unsigned long oldcrc32; 。
unsigned long crc32; 。
unsigned long oldcrc; 。
unsigned int charcnt; 。
char c,t;
oldcrc32 = 0x00000000; //初值為0 。
charcnt=0;
while (len--) { 。
t= (oldcrc32 >> 24) & 0xFF; //要移出的字節的值 。
oldcrc=crc_32_tab[t]; //根據移出的字節的值查表 。
c=DataBuf[charcnt]; //新移進來的字節值 。
oldcrc32= (oldcrc32 << 8) | c; //將新移進來的字節值添在寄存器末字節中 。
oldcrc32=oldcrc32^oldcrc; //將寄存器與查出的值進行xor 運算 。
charcnt++;
}
crc32=oldcrc32; 。
return crc32;
}
參數表可以先在PC 機上算出來,也可在程序初始化時完成。下面是用于計算參數表的c 語言 。
子程序,在Visual C++ 6.0 下編譯通過。
#include <stdio.h> 。
unsigned long int crc32_table[256]; 。
unsigned long int ulPolynomial = 0x04c11db7; 。
unsigned long int Reflect(unsigned long int ref, char ch) 。
{ unsigned long int value(0); 。
// 交換bit0 和bit7,bit1 和bit6,類推 。
for(int i = 1; i < (ch + 1); i++) 。
{ if(ref & 1) 。
value |= 1 << (ch - i); 。
ref >>= 1; } 。
return value;
}
init_crc32_table() 。
{ unsigned long int crc,temp; 。
// 256 個值
for(int i = 0; i <= 0xFF; i++) 。
{ temp=Reflect(i, 8); 。
crc32_table[i]= temp<< 24; 。
for (int j = 0; j < 8; j++){ 。
unsigned long int t1,t2; 。
unsigned long int flag=crc32_table[i]&0x80000000; 。
t1=(crc32_table[i] << 1); 。
if(flag==0)
t2=0;
else
t2=ulPolynomial; 。
crc32_table[i] =t1^t2 ; } 。
crc=crc32_table[i]; 。
crc32_table[i] = Reflect(crc32_table[i], 32); 。
}