WangScaler: 一个用心创作的作者。声明:才疏学浅,如有错误,恳请指正。
HJ212文档
先来看看官方HJ212文档关于CRC16的描述:
如果你在网上搜CRC16的代码以及使用在线的CRC16算出来的结果和我们HJ212的是不一样的,所以这篇文章我标注了HJ212的CRC16校验。
那么开始吧撸我们的代码吧。官方的文档已经将算法描述的很清楚了,我们只需要将文档的内容翻译成代码即可。
代码如下
def crcFast(text):
"""
HJ212-2017 crc16效验 wangscaler
:param text: 待效验的字符串
:return: result
"""
data = bytearray(text, encoding='utf-8')
crc = 0xffff
dxs = 0xa001
for i in range(len(data)):
hibyte = crc >> 8
crc = hibyte ^ data[i]
for j in range(8):
sbit = crc & 0x0001
crc = crc >> 1
if sbit == 1:
crc ^= dxs
data=str(hex(crc)[2:]).zfill(4)
return data
这里我给最后的结果进行了补全4位,因为在测试过程中,出现了报文的检验码三位导致TcpServer解析失败。
根据HJ212的官方文档的介绍可知检验码是四位的,开始我怀疑我的CRC16生成的代码是错误的,仔细对比了文档 ,我也查阅了相关的资料,发现应该不是我写错了,而且其他报文都是正常返回结果,于是我找到官方的示例代码测试我的报文。
官方C源码
#include <stdio.h>
int main(void) {
int a;
a=CRC16_Checkout("QN=20200828112638954;ST=91;CN=9012;PW=123456;MN=sss;Flage=5;CP=&&ExeRtn=1&&",75);
printf("%x",a);
return 0;}
int CRC16_Checkout ( char *puchMsg,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;
}
大家需要C语言版本的,可以直接使用官方的源码。对了,我测试的三位CRC的报文如下:
QN=20200828112638954;ST=91;CN=9012;PW=123456;MN=sss;Flage=5;CP=&&ExeRtn=1&&
经过测试官方的源码解析出来的CRC校验码也是三位。测试结果如下图:
我再次去网上查阅了相关的资料,发现有的作者像我一样做了补全,有的作者没有补全。
我认为补全更合理,但是HJ212官方给的C语言源码是没有补的,不知道是当时没考虑到还是怎样。
总结
总之,你是否补全应该取决于你们的公司内部协商的结果,即客户端和服务端保持一致即可,要么都补全,要么都不补全,个人建议补全,如果你认为我的想法有错误,恳请指正。
本人本篇CSDN原文,请戳HJ212_CRC16校检 _Python.感谢您的观看!
来都来了,点个赞再走呗!关注WangScaler,祝你升职、加薪、不提桶!