之前在2017年2月份发布过一个主题,也是关于CRC16的,现在我直接把函数写出来,希望能帮到有需要的朋友。对于在线监测设备数据传输标准来说,CRC16校验算法有基于通用modbus协议的,有基于环保局HJT-212协议的,以下两个函数算出来的结果都已通过现场数据包验证。
//通用modbus CRC校验算法
func modbusCRC(dataString string) string {
crc := 0xFFFF
length := len(dataString)
for i := 0; i < length; i++ {
//通用modbus取寄存器的低8位参与异或运算
crc = ((crc << 8) >> 8) ^ int(dataString[i])
for j := 0; j < 8; j++ {
flag := crc & 0x0001
crc >>= 1
if flag == 1 {
crc ^= 0xA001
}
}
}
//得到的十六进制校验码是按照高字节在前低字节在后的字符串
//要翻转,按照低字节在前高字节在后
//校验码必须是4个字符,不足4位的需要在开头补0
hex := strconv.FormatInt(int64(crc), 16) //格式化为16进制字符串
tmp := hex[2:] + hex[:2]
if len(tmp) == 3 {
tmp = "0" + tmp
}
return tmp
}
//HJ212 CRC校验算法
func hjt212CRC(dataString string) string {
crc := 0xFFFF
length := len(dataString)
for i := 0; i < length; i++ {
//hj212取寄存器的高8位参与异或运算
crc = (crc >> 8) ^ int(dataString[i])
for j := 0; j < 8; j++ {
flag := crc & 0x0001
crc >>= 1
if flag == 1 {
crc ^= 0xA001
}
}
}
//因为是基于右移位运算的结果,得到的本身就是低字节在前高字节在后的结果
//不足4位的需要在开头补0
hex := strconv.FormatInt(int64(crc), 16)
if len(hex) == 3 {
hex = "0" + hex
}
return hex
}
![捕获.PNG](http://studygolang.qiniudn.com/170728/5155c4ab390e097e2da06e6889b9312f.PNG)