一、題外話
說來慚愧,一開始是考慮寫關於CRC檢錯技術更深層次數學原理的,然而在翻看《Basic Algebra》后,我果斷放棄了這種不切實際的想法。個人覺得不是因為本人數學水平差或者能力差,而是研究生教材知識概念具有一定的連貫性,需要花大量時間研讀。不過呢,我還是找到一本適合了解CRC技術的著作《糾錯碼的代數理論》---馮克勤,對數學感興趣的朋友也可以在業余時間品讀一下全書。
用國內搜索引擎搜索關於CRC檢錯技術的文章或者博客,內容也基本都是千篇一律,基本都是介紹如何模2運算。寫下這篇文章,希望能夠彌補一下國內所謂技術文章的部分不足之處。當然,最主要的還是幫助自己和讀者有所提高。
二、循環冗余檢錯來源
CRC這個縮略詞,在我看來可以有兩種理解:一種是Cyclic Redundancy Check,即循環冗余檢錯技術;另一種則是Cyclic Redundance Code,即循環冗余校檢碼。在計算機網絡中,基本上都是使用前一種,但是我也是見過能夠理解成后者的說法的。
我第一次接觸到CRC這個詞是在計算機網絡教材講數據鏈路層幀的差錯檢測部分。實際的網絡通信鏈路並非是理想的,即在網絡通信中自身的電磁信號由於會受到外界電磁波或脈沖干擾的影響,會在比特傳輸過程中出現比特差錯(屬於傳輸差錯的一種),因此為了保證計算機網絡數據傳輸的可靠性,在網路傳輸數據時,必須采用差錯檢測措施。
在計算機網絡發展過程中,數學起到了至關重要的作用。正當通信專家對差錯檢測措施一籌莫展的時候,團隊中的數學家將抽象代數中的二元素伽羅瓦域(GF(2))引入,告訴我們可以通過數學手段解決數據的比特差錯檢測問題。其余的情況只能靠你們腦補了。
三、循環冗余檢錯原理
《計算機網絡 第五版》---謝希仁所著的教材通過例子對循環冗余檢驗原理的原理說明如下:
在發送端,先把數據划分為組,假定每組k個比特。現假定待傳送的數據M=101001(k=6)。CRC運算就是在數據M的后面添加供差錯檢測用的n位冗余碼,然后構成一個幀發送出去,一共發送(k+n)位。在所要發送的數據后面增加n位的冗余碼,雖然增大了數據傳輸的開銷,但卻可以進行差錯檢測。當傳輸可能出現錯誤時,付出這種代價往往是很值得的。
這n位冗余碼可用以下方法得出。用二進制的模2運算進行乘M的運算,這相當於在M后面添加n個0。得到的(k+n)位的數除以收發雙方事先商定的長度為(n+1)位除數P,得出的商是Q而余數是R(n位,比P少一位)。關於除數P下面還要介紹。在圖1所示的例子中,M=101001(即k=6)。假定除數P=1103(即n=3)。經模2除法運算后的結果是:商Q=110101(這個商並沒有什么用處),而余數R=001。這個余數R就作為冗余碼拼接在數據M的后面發送出去。這種為了進行檢錯而添加的冗余碼常稱為幀檢驗序列FCS(Frame Check Sequence)。因此加上FCS后發送的幀是101001001(即
),共有(k+n)位。
圖1 循環冗余檢測原理例子
順便說一下,循環冗余檢驗CRC和幀檢驗序列FCS並不是同一概念。CRC是一種檢錯方法,而FCS是添加在數據后面的冗余碼,在檢錯方法上可以選用CRC,但也可以不選用CRC。
在接受端把接收到的數據以幀為單位進行CRC檢驗:把收到的每一個幀都除以同樣的除數P(模2運算),然后檢查得到的余數R。
如果在傳輸過程中無差錯,那么經過CRC檢驗后得出的余數R肯定是0。但如果出現誤碼,那么余數R仍等於零的概率是非常非常小的(可以通過不太復雜的概率計算得出)。
總之,在接收端對收到的每一幀經過CRC檢驗后,有以下兩種情況:
1)若得出的余數R=0,則判定這個幀沒有差錯,即接受(accept);
2)若余數R!=0,則判定這個幀有差錯,即丟棄(discard)。
一種較方便的方法時用多項式來表示循環冗余檢驗過程。在上面的例子中,用多項式 表示上面的除數P=1101(最高位對應於
,最低位對應於
)。多項式P(X)稱為生成多項式。現在廣泛使用的生成多項式P(X)有以下幾種:
在數據鏈路層,發送端幀檢驗序列FCS的生成和接收端的CRC檢驗都是用硬件完成的,處理很迅速,因此並不會延誤數據的傳輸。
小結:
小結一下上述教材內容所提到的內容:


-----------------------------------------------------------------------------------上 帝 的 分 界 線------------------------------------------------------------------------------
這部分談論的是CRC檢錯技術基於的數學原理,參考文章是GF(2)---wikipedia。
GF(2) (also F2, Z/2Z or Z2) is the Galois field of two elements. It is the smallest finite field.
wikipedia給出的定義如下:GF(2)是二元素伽羅瓦域,也是最小的有限域。
"模2運算"類比二進制運算的差別---無進、退位是由GF(2)性質決定的。
小結:
模2運算是特殊的四則運算,分為加模2運算、減模2運算、乘模2運算、除模2運算。
四、循環冗余檢錯實戰
首先分析生成多項式,顯然n=3,因此循環冗余碼應為3位二進制數。生成多項式代表的二進制除數P=1001,發送的數據為101110,則真實的被除數為101110000。進行減模2運算(異或運算)如下:
圖4 模2運算步驟
於是得到FCS為011,因此發送數據實際為101110011(除以1001余數為0,讀者可自行嘗試)。注意到,在運算的時候,每次都會往后退一位,即第一位每次都是被消掉的。
五、曾經的困惑暨反思
當我一開始接觸計算網絡中CRC檢測技術的時候,由於經驗以及知識的匱乏,一直有一個問題困擾着我:如果網卡在發送幀時自動添加FCS到幀尾,那么接收端是如何判斷的呢?接收端又不知道發送端用的除數P是多少。
現在回想起來,其實這種質問的想法似乎還挺有道理的。對於這個問題,其實這篇文章當中已經給出了問題的答案:計算機網絡通信中,我們對生成多項式(除數)作了統一的標准,即針對不同的幀,發送端網卡添加不同的FCS,而接受端網卡知道相應幀該用CRC-16還是CRC-32來檢錯。
問題解決了,接着簡單談談在學習CRC檢錯技術后的有啥收獲吧。說實在的,之前只知道線性代數、數論等在計算機算法領域有着廣泛的應用,沒有想到計算機領域還用到了群論這門高深的學問。莎士比亞有句名言:"聰明的人總認為自己是笨蛋,而笨蛋卻總以為自己很聰明"。再接再勵,在工作中堅持學習吧。