關(guān)于CRC校驗(yàn)實(shí)現(xiàn)程序解釋(CRC16為例)

本文本文主要說兩件事,一是對(duì)于網(wǎng)上一些Demo的解釋,借用網(wǎng)友思路的Demo,如有雷同純屬巧合。二是關(guān)于數(shù)據(jù)反轉(zhuǎn)的問題。

在《CRC原理——為什么算出來的CRC校驗(yàn)碼結(jié)果總不一樣?》原文鏈接(http://www.itdecent.cn/p/2551ea7dbb14)中解釋了關(guān)于CRC的一些基本概念,這里談?wù)勍ㄟ^高級(jí)語言編程的實(shí)現(xiàn)思路。

CRC的實(shí)現(xiàn)步驟(以crc16為例,寬度為16位):

(1)確定模型標(biāo)準(zhǔn)

(2)將待發(fā)送數(shù)據(jù)與預(yù)定初始值進(jìn)行異或得到新的數(shù)據(jù)M

(2)在M后面(右側(cè))加上16個(gè)0得到數(shù)據(jù)N

(3)將N與模型標(biāo)準(zhǔn)除數(shù)進(jìn)行異或,得到余數(shù)

(4)將余數(shù)與結(jié)果異或值進(jìn)行異或,得到目標(biāo)值

這里不含輸入輸出值的正反轉(zhuǎn)。我們很容易會(huì)發(fā)現(xiàn)一些問題,當(dāng)所處理的數(shù)據(jù)量不大時(shí),這樣的方法是沒有問題的,但實(shí)際上我們一般傳遞的數(shù)據(jù)都是非常巨大的,如果通過上述方案,恐怕計(jì)算機(jī)的空間都不夠我們使用的,所以我們需要用另一種方法,這里引用網(wǎng)友的思路(不知道誰的,僅適用于常用的8位數(shù)據(jù)傳輸,校驗(yàn)寬度為16位,無反轉(zhuǎn)):

(1)預(yù)制一個(gè)16位的存儲(chǔ)空間CRC,并賦初始值

(2)將要發(fā)送的數(shù)據(jù)打包成一個(gè)Byte數(shù)組(將數(shù)據(jù)分成多個(gè)Byte存儲(chǔ))

(3)將第一個(gè)數(shù)據(jù)左移8位并與CRC當(dāng)前值進(jìn)行異或,結(jié)果放入CRC

(4)判斷當(dāng)前CRC的最高位(MSB)是否為1,若為1,則左移一位,將MSB移出,并在LSB(最低位)補(bǔ)0,將新的數(shù)據(jù)與簡記式Poly進(jìn)行異或,結(jié)果存入CRC;

若MSB為0則只進(jìn)行左移操作。

(5)重復(fù)步驟3-4直至8個(gè)數(shù)據(jù)移動(dòng)完畢,此時(shí)CRC中的值就是我們要的校驗(yàn)碼。

以下附上一段網(wǎng)上https://blog.csdn.net/u012923751/article/details/80352325的C代碼

這里我再解釋以下變量,如果采用的是左移方式的計(jì)算,多項(xiàng)式定為G(X)=X16+X15+X2+1(16#18005),則POLY采用的值應(yīng)該是16#8005(簡記式),其實(shí)我們可以看得到這個(gè)算法本身就是手工除法的做法了,不過還是需要驗(yàn)證一下。

我這里選用數(shù)據(jù)為16#AA,多項(xiàng)式沿用16#18005,初始值為0,結(jié)果異或值為0,不反轉(zhuǎn),其手工計(jì)算方法如下:


接下來我們驗(yàn)證一下C語言算法:


結(jié)果是一致的。

這種算法的好處是,解決了之前說的數(shù)據(jù)量的問題,每次只處理8個(gè)位,等到所有數(shù)據(jù)處理完后就能得到我們要的數(shù)值,其中應(yīng)用了模2除法交換特性就不多說了。

這是最直接的計(jì)算方法,也非常容易理解,但是實(shí)際運(yùn)用過程中,我們還會(huì)遇到數(shù)據(jù)反轉(zhuǎn)的情況,這里以CRC_16 Modbus為例,其二項(xiàng)式為16#18005,初始值16#FFFF,結(jié)果異或值16#0000,輸入值輸出值均反轉(zhuǎn)。

出現(xiàn)這種情況的原因其實(shí)就是因?yàn)镸odbus在傳輸數(shù)據(jù)的時(shí)候是低位優(yōu)先的,也就是它是從0位出去的,然后接收端是從0位接收的,因此,如果我們要進(jìn)行計(jì)算,那就要重寫一個(gè)算法,先把原始數(shù)據(jù)反轉(zhuǎn)過來,這就增加了程序的工作量。因此,程序員發(fā)明了另一個(gè)方法,使用反轉(zhuǎn)二項(xiàng)式來解決這個(gè)問題。

先用一個(gè)實(shí)例來說明一下,后面我們解釋反轉(zhuǎn)算法的合理性。

以下實(shí)例采用CRC16 Modbus 輸入輸出反轉(zhuǎn),初始值16#FFFF,多項(xiàng)式16#18005

反轉(zhuǎn)算法的思路是:

(1)預(yù)制一個(gè)16位的存儲(chǔ)空間Preset,并賦初始值(如16#FFFF)

(2)將要發(fā)送的數(shù)據(jù)打包成一個(gè)Byte數(shù)組(將數(shù)據(jù)分成多個(gè)Byte存儲(chǔ))

(3)將第一個(gè)數(shù)據(jù)左移8位并與CRC當(dāng)前值進(jìn)行異或,結(jié)果放入Preset

(4)判斷當(dāng)前CRC的最低位(LSB)是否為1,若為1,則右移一位,將LSB移出,并在MSB(最高位)補(bǔ)0,將新的數(shù)據(jù)與簡記式16#A001(16#8005反轉(zhuǎn))進(jìn)行異或,結(jié)果存入Preset;

若LSB為0則只進(jìn)行右移操作。

(5)重復(fù)步驟3-4直至8個(gè)數(shù)據(jù)移動(dòng)完畢,此時(shí)CRC中的值就是我們要的校驗(yàn)碼。

以下為SCL源碼:

反轉(zhuǎn)計(jì)算其實(shí)是一種反向除法,利用的是模2除法不借位特性,但為什么這么做呢?

先做一個(gè)理論分析,假設(shè)我們發(fā)送數(shù)據(jù)16#AB(1010 1011),這是正向發(fā)送,但由于modbus的LSB優(yōu)先傳輸特點(diǎn),接收方實(shí)際收到的數(shù)據(jù)為1101 0101,但它還是會(huì)使用16#18005來進(jìn)行計(jì)算,因此,兩邊其實(shí)是一個(gè)鏡像關(guān)系。

語言能力有限,接下來就以16#AB(1010 1011)來驗(yàn)證一下算法的正確性,這里初始值設(shè)為0,方便計(jì)算,不影響程序:

首先是發(fā)送方:


然后再看接收方,接收方收到的數(shù)據(jù)應(yīng)該為1101 0101 1000+0010 1111 1101

驗(yàn)算如下:


接收到的驗(yàn)算無余數(shù),證明結(jié)果正確,至于反轉(zhuǎn)為什么是16#A001而不是16#14001,與16#8005的結(jié)果是一樣的,在這套算法中,首位的1被舍去了,反轉(zhuǎn)算法則應(yīng)該舍去末尾的1。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 首先要講一下CRC16是什么 。 CRC是一種常見的校驗(yàn),而CRC16呢,主要是因?yàn)樾r?yàn)結(jié)果是16個(gè)位,當(dāng)然還有C...
    一路向東_lxd閱讀 24,365評(píng)論 1 4
  • 電力系統(tǒng)是一個(gè)綜合化的系統(tǒng),作為一個(gè)熟練的電工,對(duì)于通信有著一定的認(rèn)識(shí)。否則很多問題,我們將無從下手。首先我們從廣...
    洪城小電工閱讀 120,047評(píng)論 8 34
  • 一、為什么要進(jìn)行數(shù)據(jù)校驗(yàn) 數(shù)據(jù)校驗(yàn)是為保證數(shù)據(jù)的完整性,用一種指定的算法對(duì)原始數(shù)據(jù)計(jì)算出的一個(gè)校驗(yàn)值。接收方用同樣...
    用電熱毯烤豬閱讀 20,485評(píng)論 0 49
  • 最近剛好有時(shí)間,整理了一下關(guān)于CRC的資料,詳細(xì)對(duì)比了下程序的實(shí)現(xiàn)過程和原理,當(dāng)然,高手都是不在意的。 本文主要介...
    漠漠彡閱讀 26,910評(píng)論 1 10
  • 詳解大端模式和小端模式 嵌入式開發(fā)交流群280352802,歡迎加入! 一、大端模式和小端模式的起源 關(guān)于...
    l日月之明l閱讀 1,259評(píng)論 0 0

友情鏈接更多精彩內(nèi)容