在Modbus或环保212协议中,数据的校检码(CRC-16)由两个字节16位构成。而一般电气、自动化仪表的crc16校验,多项式码选用16进制A001。
CRC的计算方式如下:
在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或,之后对CRC寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB移位后已经被移出CRC寄存器)如果为,则把寄存器与预定义的多项式码进行异或,否则如果LSB为零,则无需进行异或。重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位,所有的字符处理完成后CRC寄存器内的值即为最终的CRC值。
Go 语言实现如下:
// 传入数据内容,返回 crc校验码
func Crc16Check(data []byte) []byte {
var crc16 uint16 = 0xFFFF
l := len(data)
for i := 0; i < l; i++ {
crc16 ^= uint16(data[i])
for j := 0; j < 8; j++ {
if crc16&0x0001 > 0 {
crc16 = (crc16 >> 1) ^ 0xA001
} else {
crc16 >>= 1
}
}
}
packet := make([]byte, 2)
packet[1] = byte(crc16 & 0xff)
packet[0] = byte(crc16 >> 8)
return packet
}