CRC校驗(迴圈冗餘校驗)小知識 CRC即迴圈冗餘校驗碼(Cyclic Redundancy Check):是數據通信領域中最常用的一種查錯校驗碼,其特征是信息欄位和校驗欄位的長度可以任意選定。迴圈冗餘檢查(CRC)是一種數據傳輸檢錯功能,對數據進行多項式計算,並將得到的結果附在幀的後面,接收設備也 ...
CRC校驗(迴圈冗餘校驗)小知識
CRC即迴圈冗餘校驗碼(Cyclic Redundancy Check):是數據通信領域中最常用的一種查錯校驗碼,其特征是信息欄位和校驗欄位的長度可以任意選定。迴圈冗餘檢查(CRC)是一種數據傳輸檢錯功能,對數據進行多項式計算,並將得到的結果附在幀的後面,接收設備也執行類似的演算法,以保證數據傳輸的正確性和完整性。
CRC演算法參數模型解釋:
NAME:參數模型名稱。
WIDTH:寬度,即CRC比特數。
POLY:生成項的簡寫,以16進位表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成項是0x104C11DB7。
INIT:這是演算法開始時寄存器(crc)的初始化預置值,十六進位表示。
REFIN:待測數據的每個位元組是否按位反轉,True或False。
REFOUT:在計算後之後,異或輸出之前,整個數據是否按位反轉,True或False。
XOROUT:計算結果與此參數異或後得到最終的CRC值。
CRC16 Modbus主要實現方法
/// <summary> /// CRC16_Modbus效驗 /// </summary> /// <param name="byteData">要進行計算的位元組數組</param> /// <returns>計算後的數組</returns> public static byte[] ToModbus(byte[] byteData) { byte[] CRC = new byte[2]; UInt16 wCrc = 0xFFFF; for (int i = 0; i < byteData.Length; i++) { wCrc ^= Convert.ToUInt16(byteData[i]); for (int j = 0; j < 8; j++) { if ((wCrc & 0x0001) == 1) { wCrc >>= 1; wCrc ^= 0xA001;//異或多項式 } else { wCrc >>= 1; } } } CRC[1] = (byte)((wCrc & 0xFF00) >> 8);//高位在後 CRC[0] = (byte)(wCrc & 0x00FF); //低位在前 return CRC; }
/// <summary> /// CRC16_Modbus效驗 /// </summary> /// <param name="byteData">要進行計算的位元組數組</param> /// <param name="byteLength">長度</param> /// <returns>計算後的數組</returns> public static byte[] ToModbus(byte[] byteData, int byteLength) { byte[] CRC = new byte[2]; UInt16 wCrc = 0xFFFF; for (int i = 0; i < byteLength; i++) { wCrc ^= Convert.ToUInt16(byteData[i]); for (int j = 0; j < 8; j++) { if ((wCrc & 0x0001) == 1) { wCrc >>= 1; wCrc ^= 0xA001;//異或多項式 } else { wCrc >>= 1; } } } CRC[1] = (byte)((wCrc & 0xFF00) >> 8);//高位在後 CRC[0] = (byte)(wCrc & 0x00FF); //低位在前 return CRC; }
CRC16 Modbus(LSB-MSB)通訊中校驗位元組格式為LSB-MSB,擴展方法可以忽略。
註意:MODBUS 通訊中校驗位元組格式為LSB-MSB,即低位元組在前。
/// <summary> /// CRC16_LSB-MSB效驗 /// </summary> /// <param name="byteData">要進行計算的位元組數組</param> /// <returns>計算後的數組</returns> public static byte[] ToMsbLsb(byte[] byteData) { byte[] CRC = new byte[2]; byte[] crcSwtich = new byte[2]; CRC = ToModbus(byteData); crcSwtich[0] = CRC[1]; //高位在後 crcSwtich[1] = CRC[0]; //低位在前 return crcSwtich; }
常見CRC參數模型如下:
CRC演算法名稱 | 多項式公式 | 寬度 | 多項式 | 初始值 | 結果異或值 | 輸入值反轉 | 輸出值反轉 |
---|---|---|---|---|---|---|---|
CRC-4/ITU | x4 + x + 1 | 4 | 03 | 00 | 00 | true | true |
CRC-5/EPC | x4 + x3 + 1 | 5 | 09 | 09 | 00 | false | false |
CRC-5/ITU | x5 + x4 + x2 + 1 | 5 | 15 | 00 | 00 | true | true |
CRC-5/USB | x5 + x2 + 1 | 5 | 05 | 1F | 1F | true | true |
CRC-6/ITU | x6 + x + 1 | 6 | 03 | 00 | 00 | true | true |
CRC-7/MMC | x7 + x3 + 1 | 7 | 09 | 00 | 00 | false | false |
CRC-8 | x8 + x2 + x + 1 | 8 | 07 | 00 | 00 | false | false |
CRC-8/ITU | x8 + x2 + x + 1 | 8 | 07 | 00 | 55 | false | false |
CRC-8/ROHC | x8 + x2 + x + 1 | 8 | 07 | FF | 00 | true | true |
CRC-8/MAXIM | x8 + x5 + x4 + 1 | 8 | 31 | 00 | 00 | true | true |
CRC-16/IBM | x6 + x5 + x2 + 1 | 16 | 8005 | 0000 | 0000 | true | true |
CRC-16/MAXIM | x6 + x5 + x2 + 1 | 16 | 8005 | 0000 | FFFF | true | true |
CRC-16/USB | x6 + x5 + x2 + 1 | 16 | 8005 | FFFF | FFFF | true | true |
CRC-16/MODBUS | x6 + x5 + x2 + 1 | 16 | 8005 | FFFF | 0000 | true | true |
CRC-16/CCITT | x6 + x2 + x5 + 1 | 16 | 1021 | 0000 | 0000 | true | true |
CRC-16/CCITT-FALSE | x6 + x2 + x5 + 1 | 16 | 1021 | FFFF | 0000 | false | false |
CRC-16/x5 | x6 + x2 + x5 + 1 | 16 | 1021 | FFFF | FFFF | true | true |
CRC-16/XMODEM | x6 + x2 + x5 + 1 | 16 | 1021 | 0000 | 0000 | false | false |
CRC-16/DNP | x6 + x3 + x2 + x1 + x0 + x8 + x6 + x5 + x2 + 1 | 16 | 3D65 | 0000 | FFFF | true | true |
CRC-32 | x2 + x6 + x3 + x2 + x6 + x2 + x1 + x0 + x8 + x7 + x5 + x4 + x2 + x + 1 | 32 | 04C11DB7 | FFFFFFFF | FFFFFFFF | true | true |
CRC-32/MPEG-2 | x32 + x6 + x3 + x2 + x6 + x2 + x1 + x0 + x8 + x7 + x5 + x4 + x2 + x + 1 | 32 | 04C11DB7 | FFFFFFFF | 00000000 | false | false |