python实现crc16校验

2021/8/14 1:06:01

本文主要是介绍python实现crc16校验,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

python实现crc16校验

        前阵子由于“摸鱼”需要,笔者学习了crc16校验这一小小的通信领域知识。也就有了这篇博客。在此笔者不求甚解(通信大佬可以自行略过),有错漏的地方还望指出\(^o^)/~♪(・ω・)ノ

在此笔者借鉴了这位大佬的博客https://blog.csdn.net/qq_37591637/article/details/83376006

目录

python实现crc16校验

正题

伪代码

举例

python代码 (附上注释)


正题

为什么会有crc校验?       

        在数据传输过程中,无论传输系统的设计再怎么完美,差错总会存在,这种差错可能会导致在链路上传输的一个或者多个帧被破坏,从而接受方接收到错误的数据。为尽量提高接受方收到数据的正确率,在接收方接收数据之前需要对数据进行差错检测,当且仅当检测的结果为正确时接收方才真正收下数据。

        检测的方式有多种,常见的有奇偶校验、因特网校验和循环冗余校验等。

        在计算机网络通信中运用crc校验,相对于其他校验方法就有一定的优势。CRC可以高比例的纠正信息传输过程中的错误,可以在极短的时间内完成数据校验码的计算,并迅速完成纠错过程, CRC 算法检验的检错能力极强,检测成本较低,是计算机信息通信领域最为普遍的校验方式。

一下是笔者在网上找到的crc16的校验方法:
(1)、预置1个16位的寄存器为十六进制FFFF(即全为1),称此寄存器为CRC寄存器;
(2)、把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器,高八位数据不变;
(3)、把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
(4)、如果移出位为0:重复第3步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
(5)、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
(6)、重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
(7)、将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
(8)、最后得到的CRC寄存器内容即为:CRC码。

伪代码

通过上述方法,我们不妨将它翻译成伪代码:

crc=0xFFFF;

crc=0xFFFF^data(我们将需要校验的数据赋值给data)

for( i=0;i<8; i++ )

{    

     if(第0位是1){

                crc=crc >> 1

                crc=crc ^ 0xA001

                }

     else{

              crc=crc >>1

            }

}

举例

在此笔者不求甚解,以 2D 为例,如有错漏,还请不吝赐教\(^o^)/~

另外,各位感兴趣可以到http://www.ip33.com/crc.html这个网站进行验证

(注:请选择CRC-16/MODBUS算法)

 下面是python实现效果

python代码 (附上注释)

# -*-coding:utf8-*-
ls=input().split()
# 这样你可以input数据,用空格隔开,.split在此是用来分割字符串的
datas=list(ls)
print(datas)
# 输入数据后,打印一下列表
crc16=0xFFFF
poly=0xA001
for data in datas:
# 表示将datas列表中的每一个变量赋值给data,
# 在此你可以自由输入数据,校验的次数是由你输入的数据的多少决定的
    a=int(data,16)
    # print(a)
    crc16 = a ^ crc16
    #^ 异或运算:如果两个位为“异”(值不同),则该位结果为1,否则为0。
    for i in range(8):
        # 对于每一个data,都需要右移8次,可以简单理解为对每一位都完成了校验
        if 1&(crc16) == 1:
            # crc16与上1 的结果(16位二进制)只有第0位是1或0,其他位都是0
            # & 与运算:都是1才是1,否则为0
            crc16 = crc16 >> 1
            # >>表示右移,即从高位向低位移出,最高位补0
            crc16 = crc16^poly
        else:
            crc16 = crc16 >> 1
# print(crc16)#得到的结果还是10进制
crc16=hex(int(crc16))# 将10进制转换成16进制
# print(crc16)
crc16=crc16[2:].upper()
# [2:]的作用是将4位16进制的0x消除
# .upper()可以让字母变成大写,只是为了格式好看而已,并不影响校验结果
print(crc16)
length = len(crc16)
high=crc16[0:length-2].zfill(2)
high=str(high)
# [0:length]是将得到的4位16进制切片成两个校验码而已
# 一些结果以0开头,会自动把0给吞掉 .zfill(2)可以让结果以两位二进制的形式出现
low=crc16[length-2:length].zfill(2)
low=str(low)
# print(type(low))
print("校验码低位:"+low.upper())
print("校验码高位:"+high.upper())



这篇关于python实现crc16校验的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程