版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、CRC校驗源碼分析(轉(zhuǎn))嵌入式C語言進階 2009-11-03 16:56:23 閱讀760 評論0 字號:大中小 訂閱 這兩天做項目,需要用到 CRC 校驗。以前沒搞過這東東,以為挺簡單的。結(jié)果看看別人提供的匯編源程序,居然看不懂?;藘商鞎r間研究了一下 CRC 校驗,希望我寫的這點東西能夠幫助和我有同樣困惑的朋友節(jié)省點時間。先是在網(wǎng)上下了一堆亂七八遭的資料下來,感覺都是一個模樣,全都是從 CRC 的數(shù)學原理開始,一長串的表達式看的我頭暈。第一次接觸還真難以理解。這些東西不想在這里講,隨便找一下都是一大把。我想根據(jù)源代碼來分析會比較好懂一些。
2、 費了老大功夫,才搞清楚 CRC 根據(jù)”權(quán)”(即多項表達式)的不同而相應(yīng)的源代碼也有稍許不同。以下是各種常用的權(quán)。 CRC8=X8+X5+X4+1 CRC-CCITT=X16+X12+X5+1 CRC16=X16+X15+X5+1 CRC12=X12+X11+X3+X2+1 CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1
3、+1 以下的源程序全部以 CCITT 為例。其實本質(zhì)都是一樣,搞明白一種,其他的都是小菜。 圖 1,圖 2 說明了 CRC 校驗中 CRC 值是如何計算出來的,體現(xiàn)的多項式正是 X16+X12+X5+1。 Serial Data 即是需要校驗的數(shù)據(jù)。從把數(shù)據(jù)移位開始計算,將數(shù)據(jù)位(從最低的數(shù)據(jù)位開始)逐位移入反向耦合移位寄存器(這個名詞我也不懂,覺得蠻酷的,就這樣寫了,嘿)。當所有數(shù)據(jù)位都這樣操作后,計算結(jié)束。此時,16 位移位寄存器中的內(nèi)容就是 CRC 碼。 圖中進行 XOR 運算的位與多項式的表達相
4、對應(yīng)。 X5 代表 Bit5,X12 代表 Bit12,1 自然是代表 Bit0,X16 比較特別,是指移位寄存器移出的數(shù)據(jù),即圖中的DATA OUT。可以這樣理解,與數(shù)據(jù)位做XOR運算的是上次 CRC值的 Bit15。 根據(jù)以上說明,可以依葫蘆畫瓢的寫出以下程序。(程序都是在 keil C 7.10 下調(diào)試的) typedef unsigned char uchar; typedef unsigned int ui
5、nt; code uchar crcbuff = 0x00,0x00,0x00,0x00,0x06,0x0d,0xd2,0xe3; uint crc; / CRC 碼 void main(void) uchar *ptr; crc = 0;
6、0; / CRC 初值 ptr = crcbuff; / 指向第一個 Byte 數(shù)據(jù) crc = crc16l(ptr,8); while(1); uint crc16l(uchar *
7、ptr,uchar len) / ptr 為數(shù)據(jù)指針,len 為數(shù)據(jù)長度 uchar i; while(len-) for(i=0x80; i!=0; i>>=1) if(crc&0x8000)!=0) crc<<=1; crc=0x1021;
8、 1-1 else crc<<=1; 1-2 if(*ptr&i)!=0
9、) crc=0x1021; 1-3 ptr+; return(crc); 執(zhí)行結(jié)果 crc = 0xdbc0; 程序 1-1,1-2,1-3 可以理解成移位前 crc 的 Bit15
10、與數(shù)據(jù)對應(yīng)的 Bit(*ptr&i)做 XOR運算,根據(jù)此結(jié)果來決定是否執(zhí)行 crc=0x1021。只要明白兩次異或運算與原值相同,就不難理解這個程序。 很多資料上都寫了查表法來計算,當時是怎么也沒想通。其實蠻簡單的。假設(shè)通過移位處理了 8 個 bit 的數(shù)據(jù),相當于把之前的 CRC 碼的高字節(jié)(8bit)全部移出,與一個 byte 的數(shù)據(jù)做XOR 運算,根據(jù)運算結(jié)果來選擇一個值(稱為余式),與原來的 CRC 碼再做一次 XOR 運算,就可以得到新的 CRC 碼。 不難看出,余式有 256 種可能的值,實際上就是 0255 以 X16+X12+X5+1 為權(quán)得到的 CRC碼
11、,可以通過函數(shù) crc16l來計算。以1 為例。 code test=0x01; crc = 0; ptr = test; crc = crc16l(ptr,1); 執(zhí)行結(jié)果 crc = 1021,這就是1 對應(yīng)的余式。 進一步修改函數(shù),我這里就懶得寫了,可得到 X16+X12+X5+1 的余式表。 code uint crc_ta256= / X16+X12+X5+1
12、 余式表 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0
13、xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0
14、xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a
15、33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6
16、, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, &
17、#160; 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0
18、x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0
19、x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b
20、, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 ; 根據(jù)這個思路,可以寫出以下程
21、序: uint table_crc(uchar *ptr,uchar len) / 字節(jié)查表法求 CRC uchar da; while(len-!=0) da=(uchar) (crc/256); / 以 8 位二進制數(shù)暫存 CRC 的高 8 位
22、60; crc<<=8; / 左移 8 位 crc=crc_tada*ptr; / 高字節(jié)和當前數(shù)據(jù) XOR 再查表 ptr+;
23、0; return(crc); 本質(zhì)上 CRC 計算的就是移位和異或。所以一次處理移動幾位都沒有關(guān)系,只要做相應(yīng)的處理就好了。 下面給出半字節(jié)查表的處理程序。其實和全字節(jié)是一回事。 code uint crc_ba16= 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, ;
24、60;uint ban_crc(uchar *ptr,uchar len) uchar da; while(len-!=0) da = (uchar)(crc/256)/16; crc <<= 4; crc =crc_bada(*ptr/16); da = (uchar)(crc/256)/16); crc <<= 4;
25、0; crc =crc_bada(*ptr&0x0f); ptr+; return(crc); crc_ba16和crc_ta256的前 16 個余式是一樣的。 其實講到這里,就已經(jīng)差不多了。反正當時我以為自己是懂了。結(jié)果去看別人的源代碼的時候,也是說采用 CCITT,但是是反相的。如圖 3 反過來,一切都那么陌生,faint.吐血,吐血。 仔細分析一下,也可以很容易寫出按位異或的程序。只不過由左移變成右移。 uint crc16r(unsigned char *
26、ptr, unsigned char len) unsigned char i; while(len-!=0) for(i=0x01;i!=0;i <<= 1) if(crc&0x0001)!=0) crc >>= 1; crc = 0x8408; else crc >>= 1;
27、0; if(*ptr&i)!=0) crc = 0x8408; ptr+; return(crc); 0x8408 就是 CCITT 的反轉(zhuǎn)多項式。 套用別人資料上的話 “反轉(zhuǎn)多項式是指在數(shù)據(jù)通訊時,信息字節(jié)先傳送或接收低位字節(jié),如重新排位影響 CRC計算速度,故設(shè)反轉(zhuǎn)多項式?!? 如 code uchar crcbuff = 0x00,0x00,0x00,0x00,0x06,0x0d,0x
28、d2,0xe3; 反過來就是 code uchar crcbuff_fan = 0xe3,0xd2,0x0d,0x06,0x00,0x00,0x00,0x00; crc = 0; ptr = crcbuff_fan; crc = crc16r(ptr,8); 執(zhí)行結(jié)果 crc = 0x5f1d; 如想驗證是否正確,可改 code uchar crcbuff_fan_result = 0xe3,0xd2,0x0d,0x06,0x00,0x00,0x00,0x00,0x1d,0x5f; ptr = crcbuff_fan_result; crc = crc16r(ptr,10); 執(zhí)行結(jié)果 crc = 0; 符合 CRC 校驗的原理。 請注意 0x5f1d 在數(shù)組中的排列中低位在前,正是反相運算的特點。不過當時是把我搞的暈頭轉(zhuǎn)向。 在用半字節(jié)查表法進行反相運算要特別注意一點,因為是右移,所以 CRC 移出的 4Bit與數(shù)據(jù) XOR 的操作是在 CRC 的高位端。因此
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024消防工程驗收涉及的爭議調(diào)解與法律適用合同
- 2025版集裝箱式臨時展覽中心租賃合同范本3篇
- 2024深圳汽車租賃合同書范本(含車輛租賃爭議解決)3篇
- 二零二五年度個人借款合同書撰寫指南3篇
- 二零二五年度體育行業(yè)運動員勞動合同范本3篇
- 二零二五年度☆體育賽事贊助及營銷推廣合同3篇
- 職業(yè)學校復(fù)合型人才培養(yǎng)的背景與意義
- 2024年物業(yè)租賃合同及其附加條款和服務(wù)說明
- 2025版股權(quán)融資顧問與投資并購與整合服務(wù)協(xié)議3篇
- 2024版?zhèn)|(zhì)押貸款公司借款合同示范文本3篇
- 廣東省廣州市2024年中考數(shù)學真題試卷(含答案)
- 電磁場與電磁波(第五版)完整全套教學課件
- 風能發(fā)電對養(yǎng)殖場廢棄物處理的影響
- 2024年海南省中考數(shù)學試題卷(含答案解析)
- 10MWP太陽能光伏并網(wǎng)發(fā)電電站項目電站的技術(shù)設(shè)計方案
- 孤殘兒童護理員技能鑒定考試題庫(含答案)
- 2024新冀教版英語初一上單詞默寫表
- ISO∕TR 56004-2019創(chuàng)新管理評估-指南(雷澤佳譯-2024)
- 2024年全國房地產(chǎn)估價師之估價原理與方法考試高頻題(附答案)
- DL-T5142-2012火力發(fā)電廠除灰設(shè)計技術(shù)規(guī)程
- 2024年晉城職業(yè)技術(shù)學院單招職業(yè)傾向性測試題庫附答案
評論
0/150
提交評論