【嵌入式算法】CRC校验算法
數(shù)據(jù)傳輸過(guò)程中差錯(cuò)不可避免,接收方在收到數(shù)據(jù)后,先對(duì)數(shù)據(jù)的準(zhǔn)確性進(jìn)行校驗(yàn),異常數(shù)據(jù)特殊處理。校驗(yàn)的方式有很多,常見(jiàn)的有CRC循環(huán)冗余校驗(yàn)。CRC算法檢錯(cuò)能力強(qiáng),效率高,是信息通信領(lǐng)域最為普遍的校驗(yàn)方式。CRC校驗(yàn)算法應(yīng)用廣,且實(shí)現(xiàn)算法簡(jiǎn)單,但其背后的涉及的糾錯(cuò)碼的代數(shù)理論,不是一般人可以理解的。所以,在不理解循環(huán)校驗(yàn)原理的基礎(chǔ)上,貿(mào)然分析算法流程是不明智的,根據(jù)源碼倒推實(shí)現(xiàn)流程,也不會(huì)明白為什么要這樣執(zhí)行?一般關(guān)注CRC以應(yīng)用為主,以及為什么都是CRC16算法,得出的結(jié)果卻不同。本文的意圖只是這個(gè)。
1、CRC定義
假設(shè)要發(fā)送996這個(gè)數(shù)字,將其除以7余數(shù)為2,發(fā)送時(shí)將996-2合并后發(fā)出,接收方按同樣運(yùn)算判斷數(shù)據(jù)包是否正確。同樣的源數(shù)據(jù),因?yàn)槌龜?shù)不同而余數(shù)不同。CRC算法也是因?yàn)轭愃圃怼?/p>
CRC算法中參數(shù)解釋如下:
1、除法定為模2除法
2、除數(shù)定為多項(xiàng)式,如x16+x12+x^5+1(0x1021) 216+212+25+20=65536+4096+32+1= 69665=0x11021 。依據(jù)不可描述的標(biāo)準(zhǔn),多項(xiàng)式最高位和最低位必須為1,所以一般簡(jiǎn)化為0x1021,忽略最高位,記為Poly。
3、因?yàn)槎囗?xiàng)式長(zhǎng)度不同,一般分為CRC8、CRC16和CRC32,因?yàn)槟?除法簡(jiǎn)化為異或和移位操作,其初始值為Init。
4、還有三個(gè)參數(shù)
RefIn:待測(cè)數(shù)據(jù)的每個(gè)字節(jié)是否按位反轉(zhuǎn),TRUE或FALSE。
RefOut:在計(jì)算后之后,異或輸出之前,整個(gè)數(shù)據(jù)是否按位反轉(zhuǎn),TRUE或FALSE。
XorOut:計(jì)算結(jié)果與此參數(shù)異或后得到最終的CRC值。但是任何數(shù)與0異或還是它本身,所以該值為0時(shí)可以忽略。
5、因?yàn)槎囗?xiàng)式Poly,初始值等差異,CRC有不同的版本。理論上是多項(xiàng)式是可以隨意定義的,但是通用的標(biāo)準(zhǔn)多項(xiàng)式是經(jīng)過(guò)數(shù)學(xué)推導(dǎo)的,盡可能的保證不同的數(shù)據(jù)求出的CRC值不相同。
6、參考https://crccalc.com/ 的定義,不同場(chǎng)景使用不同的多項(xiàng)式。
2、CRC算法與模板
通用版的CRC算法如下:
CRC8
CRC16
//以CRC-16/X-25為參考 unsigned short CRC16(unsigned char *data, unsigned int len) {unsigned char i;unsigned short poly = 0x1021;//與表中的Poly列對(duì)應(yīng)unsigned short init = 0xFFFF;//與表中的Init列對(duì)應(yīng)unsigned char wChar = 0;while (len--){wChar = *(data++);//RefIn為TRUE時(shí)執(zhí)行,FALSE時(shí)刪除InvertUint8(&wChar,&wChar);init ^= (wChar << 8);for( i = 0;i < 8;i++){if(init & 0x8000){init = (init << 1) ^ poly;}else{init = init << 1;}}}//RefOut為TRUE時(shí)執(zhí)行,FALSE時(shí)刪除InvertUint16(&init,&init);//與XorOut進(jìn)行異或,若為0時(shí)執(zhí)行或不執(zhí)行沒(méi)有區(qū)別init=init^0xFFFF;return (init); }CRC8和CRC16,根據(jù)不同版本的參數(shù)差異,查表,將模板里的參數(shù)改為對(duì)應(yīng)值,即可得出對(duì)應(yīng)版本的CRC值。其中涉及到數(shù)據(jù)反轉(zhuǎn)的代碼如下:
void InvertUint8(unsigned char *DesBuf, unsigned char *SrcBuf) {int i;unsigned char temp = 0;for(i = 0; i < 8; i++){if(SrcBuf[0] & (1 << i)){temp |= 1 << (7 - i);}}*DesBuf = temp; }void InvertUint16(unsigned short *DesBuf, unsigned short *SrcBuf) {int i;unsigned short temp = 0;for(i = 0; i < 16; i++){if(SrcBuf[0] & (1 << i)){temp |= 1 << (15 - i);}}*DesBuf = temp; }3、查表
針對(duì)上面的代碼,求解CRC移位異或運(yùn)算的循環(huán)體,對(duì)時(shí)間要求較高的場(chǎng)景,可以提前計(jì)算生成數(shù)值表,以空間換時(shí)間。
確定poly后,假設(shè)init為0-255,求出256個(gè)參數(shù),轉(zhuǎn)為一維數(shù)組。如上,以CRC-8/ITU為例,生成數(shù)組如下:
原來(lái)的直接計(jì)算改為查表,如下:
對(duì)于CRC16也可以使用查表法。
總結(jié)
以上是生活随笔為你收集整理的【嵌入式算法】CRC校验算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 汽车故障检测仪计算机教程,如何使用汽车故
- 下一篇: cad怎样弄出放线的坐标_利用CAD绘制