RS編碼-Python工具包使用

前言

最近學習二維碼相關知識,遇到了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 66
    
    binary_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/2位信息

ecc=RSCodec(6)#糾錯碼字長度,可糾正n/2個誤讀

編碼二進制

#編碼
byte_msg=ecc.encode('Bingo007') #5個字符+6個糾錯字=11字符=11*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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章