前言
最近学习二维码相关知识,遇到了ReedSolomon
编码,简称RS编码,中文名里德所罗门编码。遇到的问题是使用的工具包返回的编码是bytearray
类型,而二维码是二进制01
编码,所以本博客主要验证,如何将bytearray
类型转为二进制,随机污染,再利用RS编码纠错,最后解码为传递信息。
RS编码使用的工具包戳这里reedsolomon
直接安装:
pip install reedsolo
预备
首先看如何将字符串转换为bytearray
的格式,然后转换为8位二进制表示,最后再转换回bytearray
格式,最后得到原字符串
输入ASCII码
-
编码信息->bytearray->二进制
使用format
函数,将bytearray
中存储的十进制数转换为二进制aa=bytearray(b'AB') #原信息AB for i in aa:print(i) #65 66binary_code=''.join(format(x,'08b') for x in aa) #转二进制 print(len(binary_code),binary_code) #0100000101000010
-
二进制->
bytearray
->原信息bytes_msg=bytes(int(binary_code[i:i+8],2)for i in range(0,len(binary_code),8)) array_msg=bytearray(bytes_msg) print(array_msg) #bytearray(b'AB')
或者直接使用
chr
把十进制转换为字符decode_msg=''.join(chr(int(binary_code[i:i+8],2))for i in range(0,len(binary_code),8)) print(decode_msg) #AB
中文
相对于ASCII码多了一点,编码bytearray
的时候加上utf-8
,由bytearray
解码的时候加上decode('utf-8')
aa=bytearray('小明','utf-8')
print(aa)
bytearray(b'\xe5\xb0\x8f\xe6\x98\x8e')
#转二进制
binary_code=''.join(format(x,'08b') for x in aa)
print(len(binary_code),binary_code)
#48 111001011011000010001111111001101001100010001110
#二进制转bytearray
decode_msg=bytes( int(binary_code[i:i+8],2) for i in range(0,len(binary_code),8))
decode_msg=bytearray(decode_msg)
print(decode_msg)
#bytearray(b'\xe5\xb0\x8f\xe6\x98\x8e')
decode_msg=decode_msg.decode('utf-8')
print(decode_msg)
#小明
RS编码
引入相关包:
from reedsolo import RSCodec
设置纠错码字长度,假设为n,则只能纠错n/2n/2n/2位信息
ecc=RSCodec(6)#纠错码字长度,可纠正n/2个误读
编码二进制
#编码
byte_msg=ecc.encode('Bingo007') #8个字符+6个纠错字=14字符=14*8位
print(byte_msg)
#转换为二进制
binary_code=''.join(format(x,'08b') for x in byte_msg)
print(len(binary_code),type(binary_code))
print(binary_code)
'''
bytearray(b'Bingo007\x7f\xadbG\x11\x9c')
112 <class 'str'>
0100001001101001011011100110011101101111001100000011000000110111011111111010110101100010010001110001000110011100
'''
污染二进制数据,污染第1、2、4个码字:
#污染二进制
binary_code=list(binary_code)
binary_code[0*8+2]=str(1-int(binary_code[0*8+2]))
binary_code[1*8+4]=str(1-int(binary_code[1*8+4]))
binary_code[3*8+5]=str(1-int(binary_code[3*8+5]))
# binary_code[5*8+5]=str(1-int(binary_code[3*8+5]))#再错就无法纠正信息
binary_code=''.join(binary_code)
print(binary_code)
'''
0110001001100001011011100110001101101111001100000011000000110111011111111010110101100010010001110001000110011100
'''
使用RS码纠错,需要先将二进制转换为bytearray
形式,然后再用RS
纠错,得到编码信息:
#纠错
#先转换为bytearray形式
bytes_msg=bytes(int(binary_code[i:i+8],2) for i in range(0,len(binary_code),8))
array_msg=bytearray(bytes_msg)
#再纠错
data=ecc.decode(array_msg)
msg=data.decode()
print(msg)
#Bingo007
如果再多污染一个码字,就解码失败。
总结
主要就是学习bytearray
转为二进制,然后二进制转bytearray
的知识点。
链接:https://pan.baidu.com/s/1nfdaea48X-Z6T1fkSzelbQ
提取码:9u6r