1.數據校驗過程
由於數據傳輸距離的因素影響,計算機和受控設備間的通信數據就常常出現不可預知的錯誤。為了防止這些錯誤所帶來的影響,一般在通信時采取數據校驗方法,而奇偶校驗和循環冗余碼校驗就是其中最常用的校驗算法。串行數據在傳輸過程中,由於干擾可能引起信息的錯誤,出現“誤碼”。我們把如何發現傳輸中的錯誤,叫“檢碼”;發現錯誤后,如何進行修訂,叫“檢錯”。之前,就有過提示,為了保證數據在傳輸過程中不會出錯,每個數據包后面一般都會加上校驗字節。![]()
校驗過程是發送端(TX端)和接收端(RX端)共同完成的過程。如上圖所示,首先,TX端按照用戶層協議(數據包格式)將數據根據校驗算法計算出TX校驗字節,並將TX校驗字節按照協議放在數據包的指定位置。RX端接收到數據包后,在指定位置取出TX校驗字節,同時,再將接收到的數據按規定方式計算出RX校驗字節,如果RX校驗字節與接收到的TX校驗字節相等,則說明數據包是有效的,否則就應該放棄該數據包。
2.簡單粗暴地奇偶校驗
最簡單粗暴的方法就是“奇偶校驗”了,即在傳輸字符的各位之外,再傳送一位奇/偶校驗位。可采用的策略分為奇校驗和偶校驗。2.1 奇校驗
所有傳送的位數(含字符的個數位和校驗位)中,“1”的個數為奇數,如1 0110,0101;0 0110,00012.2 偶校驗
所有傳送的位數(含字符的各位數和檢驗位)中,“1”的個數為偶數,如1 0100,0101;0 0100,0001奇偶校驗能夠檢測出信息傳輸過程中的部分錯誤的數據(一位錯誤的代碼能夠檢出,兩位及以上的錯誤代碼不能檢出)。奇偶檢驗有一個劣勢,就是他只能發現錯誤,而不能糾正錯誤;一旦發現錯誤,那么沒辦法,只能重發。但是由於奇偶校驗使用起來非常簡單,仍然被廣泛使用。但是仍存在一些良好的矯正錯誤數據的方法,並具有自動訆錯能力,如循環冗余碼(CRC)檢錯等。
3.異或校驗
異或校驗方法也是非常簡單,而且非常通用,雖然使用該方法校驗后仍存在出錯的可能,但是因為異或算法非常簡單,編程毫不費力,一般新手都用這種方法。之前介紹過的NMEA-0183無線通信協議是在異或算法基礎之上進行了一定的改進。能夠理解異或運算,並使用好異或校驗算法,會使得數據處理編程變得輕松容易。
4.CRC循環冗余碼校驗
循環冗余碼校驗(Cyclical Redundancy Check, CRC)是利用除法和余數的原理來做錯誤偵測(Error Detecting)的。實際應用時,發送裝置計算出CRC值並隨數據一同發送給接收裝置RX,RX對收到的數據重新計算CR並與收到的CRC值相比較,若兩個CRC值不同,則說明數據通信出現了錯誤,該數據包應該舍棄不用。在遠距離數據通訊中,為確保高效而無差錯的傳送數據,必須對數據進行校驗控制,而CRC是對一個傳送數據塊進行校驗,是一種非常高效的差錯控制方法。目前,主流的CRC可以分為以下幾個標准:CRC-12碼;CRC-16碼;CRC-CCITT碼;CRC-32碼。CRC-12碼通常用來傳送6-bit字符串。CRC-16及CRC-CCITT碼則用來傳送8-bit字符,其中CRC-16為美國采用,而CRC-CCITT為歐洲國家所采用。CRC-32碼用途有限。在數據存儲和數據通信領域,CRC無處不在:著名的通信協議X.25的FCS(幀檢錯序列)采用的是CRC/CCITT,ARJ/LHA等壓縮工具軟件采用的是CRC32,磁盤驅動器讀寫采用的日式CRC16,通常用到的圖像存儲格式GIF/TIFF等也是采用CRC作為檢錯手段的。4.1 CRC-16的生成過程
CRC-16碼由兩個字節構成,在開始時CRC寄存器的每一位都預置為1,然后把CRC寄存器與8-bit的數據進行異或,之后對CRC寄存器從高位向低位進行移位,在最高位(MSB)的位置補零,而最低位(LSB,移位后已經被移除CRC寄存器)如果是1,則把寄存器與預定義的多項式碼進行異或,否則如果LSB為零,就無需進行進行異或。重復上述的由高至低的移位8次,第一個8-bit數據處理完畢,用此時CRC寄存器的值與下一個8-bit數據異或並進行如前一個8-bit數據似的8次移位。所有的字符處理完成后CRC寄存器的值即為最終的CRC值。下面為CRC的計算過程:(1)設置CRC寄存器,並給其賦值FFFF(hex);(2)將數據的第一個8-bit字符與16位CRC寄存器的低8位進行異或,並把結果存入CRC寄存器;(3)CRC寄存器向右移一位,MSB補零,移出並檢查LSB;(4)如果LSB為0,重復第三步;若LSB為1,CRC寄存器與多項式碼相異或;(5)重復第3與第4步直到8次移位全部完成。此時,一個8-bit數據處理完畢;(6)重復第2至第5步直到所有數據全部處理完成;(7)最終CRC寄存器的內容即為CRC值。4.2 如何理解CRC碼?
CRC校驗是一種多項式除法:將需要發送的數據包當做一個很大的二進制數,用它來除以一個固定的二進制數,所得到的余數即是所求得的CRC校驗碼。