1 引言
接收方將接收到的二進位序列數(包括信息碼和CRC碼)除以多項式,如果餘數為0,則說明傳輸中無錯誤發生,否則說明傳輸有誤,關於其原理這裡不再多述。用軟體計算CRC碼時,接收方可以將接收到的信息碼求CRC碼,比較結果和接收到的CRC碼是否相同。
3 按位計算CRC
對於一個二進位序列數可以表示為式(3-1):
(3-1)
求此二進位序列數的CRC碼時,先乘以 後(既左移16位),再除以多項式G(X),所得的餘數既是所要求的CRC碼。如式(3-2)所示:
(3-2)
可以設: (3-3)
其中 為整數, 為16位二進位餘數。將式(3-3)代入式(3-2)得:
(3-4)
再設: (3-5)
其中 為整數, 為16位二進位餘數,將式(3-5)代入式(3-4),如上類推,最後得到:
(3-6)
根據CRC的定義,很顯然,十六位二進位數 既是我們要求的CRC碼。
式(3-5)是編程計算CRC的關鍵,它說明計算本位後的CRC碼等於上一位CRC碼乘以2後除以多項式,所得的餘數再加上本位值除以多項式所得的餘數。由此不難理解下面求CRC碼的C語言程序。*ptr指向發送緩衝區的首字節,len是要發送的總字節數,0x1021與多項式有關。
unsigned int cal_crc(unsigned char *ptr, unsigned char len) {
unsigned char i;
unsigned int crc=0;
while(len--!=0) {
for(i=0x80; i!=0; i/=2) {
if((crc0x8000)!=0) {crc*=2; crc^=0x1021;} /* 餘式CRC乘以2再求CRC */
else crc*=2;
if((*ptri)!=0) crc^=0x1021; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
按位計算CRC雖然代碼簡單,所佔用的內存比較少,但其最大的缺點就是一位一位地計算會佔用很多的處理器處理時間,尤其在高速通訊的場合,這個缺點更是不可容忍。因此下面再介紹一種按字節查表快速計算CRC的方法。
4 按字節計算CRC
不難理解,對於一個二進位序列數可以按字節表示為式(4-1),其中 為一個字節(共8位)。
(4-1)
求此二進位序列數的CRC碼時,先乘以 後(既左移16位),再除以多項式G(X),所得的餘數既是所要求的CRC碼。如式(4-2)所示:
(4-2)
可以設: (4-3)
其中 為整數, 為16位二進位餘數。將式(4-3)代入式(4-2)得:
(4-4)
因為:
(4-5)
其中 是 的高八位, 是 的低八位。將式(4-5)代入式(4-4),經整理後得:
(4-6)
再設: (4-7)
其中 為整數, 為16位二進位餘數。將式(4-7)代入式(4-6),如上類推,最後得:
(4-8)
很顯然,十六位二進位數 既是我們要求的CRC碼。
式(4-7)是編寫按字節計算CRC程序的關鍵,它說明計算本字節後的CRC碼等於上一字節餘式CRC碼的低8位左移8位後,再加上上一字節CRC右移8位(也既取高8位)和本字節之和後所求得的CRC碼,如果我們把8位二進位序列數的CRC全部計算出來,放如一個表裡,採用查表法,可以大大提高計算速度。由此不難理解下面按字節求CRC碼的C語言程序。*ptr指向發送緩衝區的首字節,len是要發送的總字節數,CRC餘式表是按0x11021多項式求出的。