(转)CRC校验算法详解
CRC(Cyclic Redundancy Check)循環冗余校驗是常用的數據校驗方法,講CRC算法的文章很多,之所以還要寫這篇,是想換一個方法介紹CRC算法,希望能讓大家更容易理解CRC算法。
先說說什么是數據校驗。數據在傳輸過程(比如通過網線在兩臺計算機間傳文件)中,由于傳輸信道的原因,可能會有誤碼現象(比如說發送數字5但接收方收到的卻是6),如何發現誤碼呢?方法是發送額外的數據讓接收方校驗是否正確,這就是數據校驗。最容易想到的校驗方法是和校驗,就是將傳送的數據(按字節方式)加起來計算出數據的總和,并將總和傳給接收方,接收方收到數據后也計算總和,并與收到的總和比較看是否相同。如果傳輸中出現誤碼,那么總和一般不會相同,從而知道有誤碼產生,可以讓發送方再發送一遍數據。
CRC校驗也是添加額外數據做為校驗碼,這就是CRC校驗碼,那么CRC校驗碼是如何得到的呢?
非常簡單,CRC校驗碼就是將數據除以某個固定的數(比如ANSI-CRC16中,這個數是0x18005),所得到的余數就是CRC校驗碼。
那這里就有一個問題,我們傳送的是一串字節數據,而不是一個數據,怎么將一串數字變成一個數據呢?這也很簡單,比如說2個字節B1,B2,那么對應的數就是(B1<<8)+B2;如果是3個字節B1,B2,B3,那么對應的數就是((B1<<16)+(B2<<8)+B3),比如數字是0x01,0x02,0x03,那么對應的數字就是0x10203;依次類推。如果字節數很多,那么對應的數就非常非常大,不過幸好CRC只需要得到余數,而不需要得到商。
從上面介紹的原理我們可以大致知道CRC校驗的準確率,在CRC8中出現了誤碼但沒發現的概率是1/256,CRC16的概率是1/65536,而CRC32的概率則是1/2^32,那已經是非常小了,所以一般在數據不多的情況下用CRC16校驗就可以了,而在整個文件的校驗中一般用CRC32校驗。
這里還有個問題,如果被除數比除數小,那么余數就是被除數本身,比如說只要傳一個字節,那么它的CRC就是它自己,為避免這種情況,在做除法之前先將它移位,使它大于除數,那么移多少位呢?這就與所選的固定除數有關了,左移位數比除數的位數少1,下面是常用標準中的除數:
CRC8:多項式是X8+X5+X4+1,對應的數字是0x131,左移8位
CRC12:多項式是X12+X11+X3+X2+1,對應的數字是0x180D,左移12位 CCITT
CRC16:多項式是X16+X12+X5+1,對應的數字是0x11021,左移16位 ANSI
CRC16:多項式是X16+X15+X2+1,對應的數字是0x18005,左移16位
CRC32:多項式是X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1,對應數字是0x104C11DB7,左移32
因此,在得到字節串對應的數字后,再將數字左移M位(比如ANSI-CRC16是左移16位),就得到了被除數。
好了,現在被除數和除數都有了,那么就要開始做除法求CRC校驗碼了。CRC除法的計算過程與我們筆算除法類似,首先是被除數與除數高位對齊后,被除數減去除數,得到了差,除數再與差的最高位對齊,進行減法,然后再對齊再減,直到差比除數小,這個差就是余數。
不過和普通減法有差別的是,CRC的加(減)法是不進(借)位的,比如10減01,它的結果是11,而不是借位減法得到的01,因此,實際上CRC的加法和減法所得的結果是一樣的,比如10加01的結果是11,10減01的結果也是11,這其實就是異或操作。
代碼:略。
原文鏈接:
https://www.cnblogs.com/wchonline/p/11698677.html
總結
以上是生活随笔為你收集整理的(转)CRC校验算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第三方支付,微信支付及支付宝的一些入门了
- 下一篇: 程序员的资源网站