簡體   English   中英

隱寫術-UnicodeDecode錯誤

[英]python - Steganography - UnicodeDecode Error

我正在編寫一個Python腳本來隱藏圖像中的數據。 它基本上隱藏了.PNG中每個像素的RGB映射中紅色的最后兩位中的位。 該腳本適用於小寫字母,但會出現句號錯誤。 它產生此錯誤:

追溯(最近一次通話):文件“ E:\\ Python \\ Steganography \\ main.py”,行65,在打印中(取消隱藏('coded-img.png'))文件“ E:\\ Python \\ Steganography \\ main。 py”,第60行,在取消隱藏消息中= bin2str(binary)文件“ E:\\ Python \\ Steganography \\ main.py”,第16行,在bin2str中,返回n.to_bytes((n.bit_length()+ 7)// 8 ,'big')。decode()UnicodeDecodeError:'utf-8'編解碼器無法解碼位置6的字節0x80:無效的起始字節

這是我的代碼:

from PIL import Image

def str2bin(message):
    binary = bin(int.from_bytes(message.encode('utf-8'), 'big'))
    return binary[2:]

def bin2str(binary):
    n = int(binary, 2)
    return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()

def hide(filename, message):
    image = Image.open(filename)
    binary = str2bin(message) + '00000000'

    data = list(image.getdata())

    newData = []

    index = 0
    for pixel in data:
        if index < len(binary):
            pixel = list(pixel)
            pixel[0] >>= 2
            pixel[0] <<= 2
            pixel[0] += int('0b' + binary[index:index+2], 2)
            pixel = tuple(pixel)
            index += 2

        newData.append(pixel)

    print(binary)

    image.putdata(newData)
    image.save('coded-'+filename, 'PNG')

def unhide(filename):
    image = Image.open(filename)
    data = image.getdata()

    binary = '0'

    index = 0

    while binary[-8:] != '00000000':
        binary += bin(data[index][0])[-2:]
        index += 1

    binary = binary[:-1]

    print(binary)
    print(index*2)

    message = bin2str(binary)
    return message


hide('img.png', 'alpha.')
print(unhide('coded-img.png'))

請幫忙。 謝謝!

您的代碼至少存在兩個問題。

第一個問題是您的編碼可能會錯位1位,因為bin()函數的輸出中不包括前導空位:

>>> bin(int.from_bytes('a'.encode('utf-8'), 'big'))[2:]
'1100001'
# This string is of odd length and (when joined with the terminating '00000000')
# turns into a still odd-length '110000100000000' which is then handled by your
# code as if there was an extra trailing zero (so that the length is even).
# During decoding you compensate for that effect with the
#
#       binary = binary[:-1]
#
# line. The latter is responsible for your stated problem when the binary
# representation of your string is in fact of even length and doesn't need
# the extra bit as in the below example:
>>> bin(int.from_bytes('.'.encode('utf-8'), 'big'))[2:]
'101110'

您最好在前面加上一個額外的空位(如果需要),將二進制字符串補充為偶數長度。

另一個問題是,在恢復隱藏消息的同時,可以通過將一個(部分恢復的)符號的前導位與另一符號的尾隨級聯來提前滿足停止條件binary[-8:] == '00000000' 例如,在以下情況下可能會發生這種情況

  • 符號@ (ASCII碼= 64,即未設置6個低階位),后跟任何ASCII碼值小於64(即未設置2個高階位)的字符;

  • 一個空格字符(ASCII碼= 32,即未設置4個低位),后跟換行符/換行符(ASCII碼= 10,即未設置4個高位)。

您可以通過要求在最后8位都未設置時對一個完整字節進行解碼來解決該錯誤:

while not (len(binary) % 8 == 0 and binary[-8:] == '00000000'):
    # ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM