Python学习笔记10:CRC32
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python学习笔记10:CRC32,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3505字,纯文字阅读大概需要6分钟。
内容图文
![Python学习笔记10:CRC32](/upload/InfoBanner/zyjiaocheng/619/d624a7b9675947f2b0ef006fee25f4bc.jpg)
基本概念
CRC全称是循环冗余校验(Cyclic Redundancy Check)。
在数据传输过程中,无论传输系统的设计再怎么完美,差错总会存在,这种差错可能会导致在链路上传输的一个或者多个帧被破坏(出现比特差错,0变为1,或者1变为0),从而接受方接收到错误的数据。为尽量提高接受方收到数据的正确率,在接收方接收数据之前需要对数据进行差错检测,当且仅当检测的结果为正确时接收方才真正收下数据。
CRC是一种用于校验通信链路上数字传输准确性的计算方法(通过某种数学运算来建立数据位和校验位的约定关系)。发送方计算机使用某公式计算出被传送数据所含信息的一个值,并将此值附在被传送数据后,接收方计算机则对同一数据进行相同的计算,应该得到相同的结果。如果这两个CRC结果不一致,则说明发送中出现了差错,接收方计算机可要求发送方计算机重新发送该数据。
CRC是一种数据错误检查技术,是一种常用的检错码,但并不能用于自动纠错。
多项式
了解了CRC的基本概念,那么接下来就要知道多项式的概念了。
以这个IEEE802.3标准CRC32多项式为例:x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x+ 1
x32则对应32bit = 1, x26则对应26bit=1,得出一个值:(1<<32)|(1<<26)|(1<<23)|(1<<22)|…|(1<<1)|(1)=0x104C11DB7,对于CRC32取低32位,则=0x4C11DB7
一般是用这个值通过一定方法生成长度为256的码表,对于CRC32,表内每个元素都为32bit。然后再用一定的方法查表最后得出CRC32值。
为什么用查表这种方法呢?因为,世界上一共就256个字符,每装载一个就运算一遍,很浪费CPU资源,不如直接把每个字符的CRC都算出来存入数组。因此,就有了CRC编码字符表。
接下来我们看下最终实现代码:
# 定义一个256个元素的全0数组
custom_crc32_table = [0 for x in range(0,256)]
def generate_crc32_table():
for i in range(256):
c = i << 24
for j in range(8):
if (c & 0x80000000):
c = (c << 1) ^ 0x04C11DB7
else:
c = c << 1
custom_crc32_table[i] = c & 0xffffffff
def getCrc32(bytes_arr):
length = len(bytes_arr)
if bytes_arr != None:
crc = 0xffffffff
for i in range(0, length):
crc = (crc << 8) ^ custom_crc32_table[(getReverse(bytes_arr[i], 8) ^ (crc >> 24)) & 0xff]
else:
crc = 0xffffffff
# - 返回计算的CRC值
crc = getReverse(crc ^ 0xffffffff, 32)
return crc
def getReverse(tempData, byte_length):
reverseData = 0
for i in range(0, byte_length):
reverseData += ((tempData>>i)&1)<<(byte_length-1-i)
return reverseData
我们再来看看使用反转后的多项式(0xEDB88320)代码实现:
# 定义一个256个元素的全0数组
reversal_crc32_table = [0 for x in range(0,256)]
def reversal_init_crc32_table():
for i in range(256):
c = i
for j in range(8):
if (c & 0x00000001):
c = (c >> 1) ^ 0xEDB88320
else:
c = c >> 1
reversal_crc32_table[i] = c & 0xffffffff
def reversal_getCrc32(bytes_arr):
length = len(bytes_arr)
if bytes_arr != None:
crc = 0xffffffff
for i in range(0, length):
crc = (crc >> 8) ^ reversal_crc32_table[ (bytes_arr[i] ^ crc) & 0xff ]
else:
crc = 0xffffffff
crc = crc ^ 0xffffffff
return crc
测试代码:
if __name__ == "__main__":
import struct
import zlib
import binascii
s = struct.pack('>i', 400)
print('当前CRC输入初始值:', (s, type(s)))
test = binascii.crc32(s) & 0xffffffff
print('算出来的CRC值:', '0x'+"{:0>8s}".format(str('%x'%test)))
test = zlib.crc32(s) & 0xffffffff
print('算出来的CRC值:', '0x'+"{:0>8s}".format(str('%x'%test)))
buf_s = [0x00, 0x00, 0x01, 0x90]
generate_crc32_table()
crc_stm = getCrc32(bytearray(buf_s)) & 0xffffffff
print('算出来的CRC值:', '0x' + "{:0>8s}".format(str('%x' % crc_stm)))
reversal_init_crc32_table()
crc_stm = reversal_getCrc32(bytearray(buf_s)) & 0xffffffff
print('反转算出来的CRC值:', '0x' + "{:0>8s}".format(str('%x' % crc_stm)))
再看看最终的运行结果:
当前CRC输入初始值: (b'\x00\x00\x01\x90', <class 'bytes'>)
算出来的CRC值: 0xc8507d19
算出来的CRC值: 0xc8507d19
算出来的CRC值: 0xc8507d19
反转算出来的CRC值: 0xc8507d19
内容总结
以上是互联网集市为您收集整理的Python学习笔记10:CRC32全部内容,希望文章能够帮你解决Python学习笔记10:CRC32所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。