关于实现CRC16校验算法的两个函数

welcome_home · 2017-07-28 02:33:03 · 6135 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-07-28 02:33:03 的主题,其中的信息可能已经有所发展或是发生改变。

之前在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


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

6135 次点击  
加入收藏 微博
1 回复  |  直到 2019-01-26 14:44:04
JGbooks
JGbooks · #1 · 6年之前

crc校验可以模仿 网上C代码的查表法,要快很多

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传