SOS,困扰了一天多,怎么使用golang编写CRC16校验函数呢?

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

这些天要写一个通信协议封解包程序,要用到CRC16校验,协议中关于CRC的资料如下图: crc.JPG

我参考了一下别人用Java写的CRC16函数

public static String getCrc(byte[] data) {
int high;
int flag;

    int wcrc = 0xffff;  
    for (int i = 0; i < data.length; i++) {  
        high = wcrc >> 8;  
        wcrc = high ^ data[i];  

        for (int j = 0; j < 8; j++) {  
            flag = wcrc & 0x0001;  
            wcrc = wcrc >> 1;  
            if (flag == 1)  
                wcrc ^= 0xa001;  
        }  
    }  
    return Integer.toHexString(wcrc);  

}

由于找不到golang现成的crc6相关的函数,它只有crc32的,然后用golang实现了一个:

func Crc16Verify(msg string) {

   //16位全为1的寄存器
   var crc uint16 = 0xFFFF   
     //高8位字节  
var HighByte uint16
     //移出的数位        
var flag uint16               

var msgBytes []byte = []byte(msg) //被校验的信息
var length int = len(msgBytes)    //被校验的信息的长度
for i := 0; i < length; i++ {
    HighByte = crc >> 8                  // 16位寄存器的高位字节
    crc = HighByte ^ uint16(msgBytes[i]) //取被校验串的一个字节与16位寄存器的高位字节进行异或运算

    for j := 0; j < 8; j++ {
        flag = crc & 0x0001 //移出的数位
        crc = crc >> 1      // 把这个 16 寄存器向右移一位

        if flag == 0x0001 { //移出位是1与多项式0xA001异或
            crc ^= 0xA001
        }
    }
}
//crc = (crc << 8) ^ (crc >> 8)//高低字节对调
fmt.Printf("%#x\n", crc)

}

在Crc16Verify("1234")的时候,输出0x9181,同时Java版本的输出9181,但是用crc16校验工具算出的是1012和c613,没有一个对得上的。

crc1.JPG 2.JPG

小弟实在不知道错在哪里了,这个问题困扰了一天多,麻烦各位go大神指教指教!


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

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

4926 次点击  
加入收藏 微博
3 回复  |  直到 2021-06-22 10:01:33
alex_023
alex_023 · #1 · 8年之前

算法不了解,但从代码上看,输入值的处理存在问题哦。 原始数值(16进制):1234,可不是字符串“1234”直接[]byte。 至少也应该用binary包来写入。比如:

    b := make([]byte, 2)
    binary.BigEndian.PutUint16(b, 0x1234)
    fmt.Printf("%x\n", b)
    Crc16Verify(b)//该方法只需要对[]byte直接位运算

希望有所帮助!

alex_023
alex_023 · #2 · 8年之前

github有一个比较好的代码,可以去看看: https://github.com/howeyc/crc16/blob/master/crc16.go

vaderboy
vaderboy · #3 · 4年之前

您好,您这个怎么解决的?

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