CRC16-HJ212-Lua版

CRC16-HJ212版

最近在开发中用到了HJ212环保数据传输标准,其中数据发送到上位机需要一道CRC16校验算法,开始以为是几种主流标准CRC16之一,但是运行之后无法得到官方的校验值十六进制1C80,对应十进制7296。

--待校验数据,正确校验结果为0x1C80 
QN=20160801085857223;ST=32;CN=1062;PW=100000;MN=010000A8900016F000169DC0;Flag=5;CP=&&RtdInterval=30&&

因为我的开发语言是Lua,网上搜索了下也没有找到Lua版本的,无奈只能重写一次了,参照官方给出的C语言版本

CRC16 校验字节的生成步骤如下: 
1) CRC16 校验寄存器赋值为 0xFFFF; 
2) 取被校验串的第一个字节赋值给临时寄存器; 
3) 临时寄存器与 CRC16 校验寄存器的高位字节进行“异或”运算,赋值给 CRC16 校验寄存器; 
4) 取 CRC16 校验寄存器最后一位赋值给检测寄存器; 
5) 把 CRC16 校验寄存器右移一位; 
6) 若检测寄存器值为 1,CRC16 校验寄存器与多项式 0xA001 进行“异或”运算,赋值给 CRC16
校验寄存器; 
7) 重复步骤 4~6,直至移出 8 位; 
8) 取被校验串的下一个字节赋值给临时寄存器; 
9) 重复步骤 3~8,直至被校验串的所有字节均被校验; 
10) 返回 CRC16 校验寄存器的值。 
校验码按照先高字节后低字节的顺序存放

C语言版本[官方]

unsigned int CRC16_Checkout ( unsigned char *puchMsg, unsigned int usDataLen ) 
{ 
	unsigned int i,j,crc_reg,check; 
	crc_reg = 0xFFFF; 
	for(i=0;i<usDataLen;i++) 
	{ 
		crc_reg = (crc_reg>>8) ^ puchMsg[i]; 
		for(j=0;j<8;j++) 
		{ 
		 check = crc_reg & 0x0001; 
		 crc_reg >>= 1; 
		 if(check==0x0001){crc_reg ^= 0xA001; } 
		} 
	} 
	return crc_reg; 
}

Lua5.3

local function crc212(data212)
    local crc_reg=0xFFFF
    local check
    for s in string.gmatch(data212, ".") do
        crc_reg= (crc_reg >> 8) ~ string.byte(s)
        for i=0,7 do
            check = crc_reg & 0x0001
            crc_reg = crc_reg >> 1
            if check==0x0001 then crc_reg = crc_reg ~ 0xA001 end
        end
    end
    return crc_reg
end

另外,LuatOS框架基于5.3开发,可是我在vscode模拟器环境下开发时,遇到太多版本不一致了,比如5.3种中的位运算符号提示非法,而我用5.1的位运算符却又编译通过了,其中Lua5.1-5.3的位运算符每个版本都不一样,踩坑,同样的问题在load( ) 以及loadstring( )上。

Lua5.1

local function crc212(data212)
    local crc_reg=0xFFFF
    local check
    for s in string.gmatch(data212, ".") do
        crc_reg=bit.rshift(crc_reg,8)
        crc_reg=bit.bxor(crc_reg,string.byte(s))
        for i=0,7 do
            check =bit.band(crc_reg,0x0001)
            crc_reg = bit.rshift(crc_reg,1)
            if check==0x0001 then crc_reg =bit.bxor(crc_reg,0xA001)  end
        end
    end
    return crc_reg
end

此外这里还写了一份Java版本的,位运算符基本和C是一致的,平平无奇

Java

	public static int crc212(String data212) {
		int crc_reg=0xFFFF;
		int check;
		byte[] dataByte=data212.getBytes();
		for (int i = 0; i < data212.length(); i++) {
			crc_reg= (crc_reg >>8) ^ dataByte[i];
			for (int j = 0; j < 8; j++) {
				check=crc_reg & 0x0001;
				crc_reg >>=1;
				if (check==0x0001) {crc_reg^=0xA001;}
			}		
		}
       return crc_reg;
    };
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值