CRC8/CRC16/CRC32查表法中表中元素是如何計算得到?
const char CRC8Table[]={
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};
上面這個龐大的數組是根據,CRC8的多項式X^8+X^5+X^4+X^0 計算出來的,但該數組到底是如何被計算出來的?如果以后想換一個多項式時要怎么辦?這就需要我們理解CRC表的計算原理了。
以表的下標為0x01 作為示例來進行計算:
首先需要明確CRC8常見的表格數據中是按照線傳輸LSB,並通過右移寄存器來判斷的,因此每次要判斷的就是寄存器的最低位LSB。同時要將多項式X^8+X^5+X^4+X^0 (也就是0x131(0011 0001))按位顛倒后得到0x8c(1000 1100),在計算過程
中做異或運算(為什么0x131中第一個1沒有被顛倒?答:因為它是隱藏的)。
具體步驟如下:
1 選擇范圍0~255(包含255)范圍內的數據,設為temp;
2 判斷temp的最低位是否為1,如果為1,先將temp右移一位,然后將temp和多項式(0x8c)進行異或運算,結果保存在temp中。如果最低位為0,則將temp右移一位;
3 重復第二步,直到temp中的8位數據全部從右移出,然后進入4步;
4 此時temp的值就是CRC8校驗值。
通過以上推導,以表的下標為0x00,按步驟1/2/3/4 計算得出的CRC表格值為0,而表格中剩下其它下標元素對應CRC值都是一樣的計算步驟。
CRC16 校驗算法
循環冗余碼校驗英文名稱為Cyclical Redundancy Check,簡稱CRC。它是利用除法及余數的原理來作錯誤偵測(Error Detecting)的。實際應用時,發送裝置計算出CRC值並隨數據一同發送給接收裝置,接收裝置對收到的數據重新計算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碼大都被采用在一種稱為Point-to-Point的同步傳輸中。
1、循環校驗碼(CRC碼):
是數據通信領域中最常用的一種差錯校驗碼,其特征是信息字段和校驗字段的長度可以任意選定。
2、生成CRC碼的基本原理:
任意一個由二進制位串組成的代碼都可以和一個系數僅為‘0’和‘1’取值的多項式一一對應。例如:代碼1010111對應的多項式為x6+x4+x2+x+1,而多項式為x5+x3+x2+x+1對應的代碼101111。
標准CRC生成多項式如下表:
名稱 | 生成多項式 | 簡記式 | 標准引用 |
CRC-4 | x4+x+1 | 3 | ITU G.704 |
CRC-8 | x8+x5+x4+1 | 0x31 | |
CRC-8 | x8+x2+x1+1 | 0x07 | |
CRC-8 | x8+x6+x4+x3+x2+x1 | 0x5E | |
CRC-12 | x12+x11+x3+x+1 | 80F | |
CRC-16 | x16+x15+x2+1 | 8005 | IBM SDLC |
CRC16-CCITT | x16+x12+x5+1 | 1021 | ISO HDLC, ITU X.25,,V.34/V.41/V.42, PPP-FCS |
CRC-32 | x32+x26+x23+...+x2+x+1 | 04C11DB7 | ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS |
CRC-32c | x32+x28+x27+...+x8+x6+1 | 1EDC6F41 | SCTP |
下面着重是CRC-16檢驗碼的生成過程。
CRC-16碼由兩個字節構成,在開始時CRC寄存器的每一位都預置為1,然后把CRC寄存器與8-bit的數據進行異或,之后對CRC寄存器從高到低進行移位,在最高位(MSB)的位置補零,而最低位(LSB,移位后已經被移出CRC寄存器)如果為
1,則把寄存器與預定義的多項式碼進行異或,否則如果 LSB為零,則無需進行異或。重復上述的由高至低的移位8次,第一個8-bit數據處理完畢,用此時CRC寄存器的值與下一個8-bit數據異或並進行如前一個數據似的8次移位。所有的字符處理完成
后CRC寄存器內的值即為最終的CRC值。
下面為CRC16的計算過程,其中生成多項式為:X16+X15+X2+1:
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值。
const uint16 CRC_Table[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
/********************************************************************************************************
** 函數名稱: CRCCode_Calibate(uint8 *Databuf,UINT16 UseDataSize);
** 功能描述: 計算報文CRC校驗碼
** 輸 入: uint8 *Databuf:要校驗的數組
uint16 UseDataSize:要校驗的數組長度
** 輸 出:
** 返 回: 返回16位CRC校驗碼
** 全局變量:
** 調用模塊:
*********************************************************************************************************/
uint16 CRCCode_Calibate(uint8 *Databuf,uint16 UseDataSize)
{
uint16 i,X,CRC_Code,CRC;
CRC_Code=0xFFFF; //CRC 校驗初始值為0xFFFF
for(i=0; i<UseDataSize; ++i)
{
X=CRC_Code^Databuf[i];
CRC_Code=(CRC_Code>>8)^CRC_Table[X&0x00FF];
}
CRC=((CRC_Code&0xFF)<<8)|((CRC_Code>>8)&0xFF);
return CRC;
}
轉自:https://blog.csdn.net/u010464679/article/details/52637518?locationNum=8&fps=1