CRC(循環冗余校驗)在線計算 http://www.ip33.com/crc.html
里面的8005的多項式值,但網上看到的算法都是用A001來異或的
-----------------------------------------------------
0x8005=1000 0000 0000 0101B
0xA001=1010 0000 0000 0001B
對比兩個二進制高低位正好是完全相反的,CRC校驗分為正向校驗與反向校驗。正向校驗高位在左,反向校驗低位在左
正向校驗使用左移位,反向校驗使用右移位
---------------------------------
Modbus協議,常規485通訊的信息發送形式如下:
地址 功能碼 數據信息 校驗碼
1byte 1byte nbyte 2byte
CRC校驗是前面幾段數據內容的校驗值,為一個16位數據,發送時,低8位在前,高8為最后。
例如:信息字段代碼為: 1011001,校驗字段為:1010。
發送方:發出的傳輸字段為: 1 0 1 1 0 0 1 1 0 10
參考文檔:
https://www.jianshu.com/p/676744381473
https://www.jianshu.com/p/c0d93c2e89ce
VB對應的算法
Public Function CRC16(Data() As Byte, ByRef bLow As Byte, ByRef bHigh As Byte) As String Dim CRC16Lo As Byte, CRC16Hi As Byte 'CRC寄存器 Dim CL As Byte, ch As Byte '多項式碼&HA001 Dim SaveHi As Byte, SaveLo As Byte Dim i As Integer Dim flag As Integer CRC16Lo = &HFF CRC16Hi = &HFF CL = 1 ch = &HA0 For i = LBound(Data) To UBound(Data) - 2 CRC16Lo = CRC16Lo Xor Data(i) '每一個數據與CRC寄存器的低8位進行異或 '右移8次 For flag = 0 To 7 '記錄一下,用來判斷移出位是0還是1 SaveHi = CRC16Hi SaveLo = CRC16Lo CRC16Hi = CRC16Hi \ 2 '高位右移一位 CRC16Lo = CRC16Lo \ 2 '低位右移一位 If ((SaveHi And &H1) = &H1) Then '如果高位字節最后一位為1 CRC16Lo = CRC16Lo Or &H80 '則低位字節右移后前面補1 End If '否則自動補0 If ((SaveLo And &H1) = &H1) Then '如果移出位為1,則與多項式碼進行異或 CRC16Hi = CRC16Hi Xor ch CRC16Lo = CRC16Lo Xor CL End If Next flag Next i Dim ReturnData(1) As Byte ReturnData(0) = CRC16Hi 'CRC高位 ReturnData(1) = CRC16Lo 'CRC低位 Dim Value As Double Value = CLng(CRC16Hi * 256) + CRC16Lo CRC16 = ReturnData bHigh = CRC16Hi bLow = CRC16Lo End Function
C# 對應的算法
public static byte[] CRC16(byte[] data) { int len = data.Length; if (len > 0) { ushort crc = 0xFFFF; for (int i = 0; i < len; i++) { crc = (ushort)(crc ^ (data[i])); for (int j = 0; j < 8; j++) { crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1); } System.Diagnostics.Debug.WriteLine("i=" + i.ToString() + ","+ crc.ToString()); } byte hi = (byte)((crc & 0xFF00) >> 8); //高位置 byte lo = (byte)(crc & 0x00FF); //低位置 return new byte[] { hi, lo }; } return new byte[] { 0, 0 }; }