1、前言
循環冗余校驗碼簡稱CRC碼,是目前使用非常廣泛的數據校驗方式.它不僅能校驗傳遞過來的數據正確性,還能篩查出哪一位出現了錯誤.它的局限性是只能校驗一位數據發生跳變,在現實世界當中數據發生跳變很大很大的概率只有一位發生變化,因此CRC碼也擁有很大的發揮舞台.
2、發送方數據處理
a、 前期准備
假設發送方A向接收方B發送一串二進制數據101001.A需要計算出K位校驗碼,放在原始數據的后面一起發送給B.
它們雙方事先約定了一個私密的二項式G(x) = x^3 + x^2 +1,這個多項式用來計算校驗碼的位數和值.二項式的設計必須符合一定的規則,G(x)的最高項和最低項的系數必須為1.通過這個二項式我們首先可以獲取K的大小,最高項x^3的冪指數3就等於K.另外通過二項式G(x)生成數據串G(x) = 1*x^3 + 1*x^2 + 0*x^1 +1*x^0 = 1101(將二項式前面的系數組合在一起就形成了數據串).數據串可以幫助我們計算出校驗碼的值.
在有些情景下,我們無法獲知多項式G(x).但直接得到了多項式生成后的數據串1101,此時怎么知道校驗碼有幾位呢?用數據串的長度減去1就是K的大小.
校驗碼的計算
從上面描述可知二進制數據101001現在需要加上3位校驗碼,而用於校驗的數據串也已經算出為1101.那通過這兩個條件如何計算出校驗碼呢?在這里采用的是模2除法.模2除法它既不向上位借位,也不比較除數和被除數的相同位數值的大小,只要以相同位數進行異或運算即可.詳細運算過程如下:
101001后面需要加上3位校驗碼,先添加3個0替代變成101001000,隨后對1101做模二除法
然后要看被除數的最高位是1還是0,是1商就上1,是0商就上0.此時被除數最高位是1,所以商為1.1再乘以1101和1010做異或運算
第一輪計算余數為0111,舍棄最高位0,將后面的0填上就變成了1110.此時被除數變成了1110,最高位仍然為1,所以商仍然上1,將1101和1101做異或運算.結果0011,舍棄最高位0,將后面的1填上,被除數就變成了0111.依次類推算到最后一位的余數為001.
只要本着被除數的最高位為幾商就寫幾的原則進行異或運算后的余數的最高位一定是0,是0就可以舍棄,繼續進行下面的運算.最后得出的最終余數001就是我們想要的3位檢驗碼.
通過這種模二除法有什么好處呢?比如說數101001后面加三個0后對1101做模二除法,最終會得到三位余數.然后將三位余數替換被除數的三個0再對1101做模二除法時,余數一定為0.換言之101001001再對1101做模二除法時余數一定為0.利用這個特性就可以做數據校驗.
3、接受方數據校驗
接受方B此時已經接受到了A傳遞過來的數據 101001001,並且他也知道事先約定的多項式g(x),他先通過g(x)計算出數據串為1101.他現在要開始做校驗操作了.讓101001001對1101做模二除法.
計算出來的余數為0,說明傳送過來的數據正確.
假如傳送過來的數據101001001第二位發生了跳變,變成了101001011,那運算結果又會如何?
最后計算出來的余數為010,並不為0,說明數據發生了跳變.而010代表數字2,指明是第二位數據出現了錯誤.細心的同學肯定會發現3位校驗碼最多只能表示8種情況,而101001001有9個數字,在最多只有一位數字發生跳變的前提下,它的錯誤情況有九種,這樣的話3位校驗碼就無法表示所有的出錯情況了.比如說101001001最高位發生了跳變.
最高位發生跳變時,被除數的最高位為0,商上0繼續運算,算到最后的余數為010.此時我們可以發現最高位(第9位)發現跳變時最后算出的余數是010,而第二位發生跳變時也是010,如果接收方算出了010,它也無法確定到底是第二位出錯還是第九位出錯,這樣就只能檢錯而不能糾錯.為了避免此類狀況的發生,多項式g(x)和信息數據的長度設計顯得尤為重要.