HJ212 CRC16校验(python)

1,302 阅读3分钟

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

WangScaler: 一个用心创作的作者。

声明:才疏学浅,如有错误,恳请指正。

HJ212文档

先来看看官方HJ212文档关于CRC16的描述:

image.png

image.png

image.png 如果你在网上搜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校验码也是三位。测试结果如下图:

image.png

我再次去网上查阅了相关的资料,发现有的作者像我一样做了补全,有的作者没有补全。 我认为补全更合理,但是HJ212官方给的C语言源码是没有补的,不知道是当时没考虑到还是怎样。

总结

总之,你是否补全应该取决于你们的公司内部协商的结果,即客户端和服务端保持一致即可,要么都补全,要么都不补全,个人建议补全,如果你认为我的想法有错误,恳请指正。

本人本篇CSDN原文,请戳HJ212_CRC16校检 _Python.感谢您的观看!

来都来了,点个赞再走呗!

关注WangScaler,祝你升职、加薪、不提桶!