从字符串输出

时间:2017-09-11 22:35:31

标签: python string python-3.x byte steganography

我使用stepic3来隐藏一些数据。多个文件被压缩成一个zip文件,这将是隐藏的消息。但是,当我使用以下代码时

from PIL import Image
import stepic

def enc_():
    im = Image.open("secret.png")
    text = str(open("source.zip", "rb").read())
    im = stepic.encode(im, text)
    im.save('stegolena.png','PNG')

def dec_():
    im1=Image.open('stegolena.png')
    out = stepic.decode(im1)
    plaintext = open("out.zip", "w")
    plaintext.write(out)
    plaintext.close()

我收到错误

  

完成追溯
  追溯(最近的呼叫最后):
  文件“C:\ Users \ Sherif \ OneDrive \ Pyhton Projects \ Kivy Tests \ simple.py”,第28行,在enc_()中   文件“C:\ Users \ Sherif \ OneDrive \ Pyhton Projects \ Kivy Tests \ simple.py”,第8行,在enc_中   im = stepic.encode(im,text)
  文件“C:\ Users \ Sherif \ OneDrive \ Pyhton Projects \ Kivy Tests \ stepic.py”,第89行,在编码中   encode_inplace(图像,数据)
  文件“C:\ Users \ Sherif \ OneDrive \ Pyhton Projects \ Kivy Tests \ stepic.py”,第75行,在encode_inplace中   for encode_imdata(image.getdata(),data)中的像素:
  在encode_imdata中输入文件“C:\ Users \ Sherif \ OneDrive \ Pyhton Projects \ Kivy Tests \ stepic.py”,第58行   byte = ord(data [i])
  TypeError:ord()期望的字符串长度为1,但是找到了int

有两种方法可以转换为字符串。

text = open("source.zip", "r", encoding='utf-8', errors='ignore').read()

带输出

PKn!K\Z

sec.txt13 byte 1.10mPKn!K\Z

sec.txtPK52

text = str(open("source.zip", "rb").read())

带输出

b'PK\x03\x04\x14\x00\x00\x00\x00\x00n\x8f!K\\\xac\xdaZ\r\x00\x00\x00\r\x00\x00\x00\x07\x00\x00\x00sec.txt13 byte 1.10mPK\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00n\x8f!K\\\xac\xdaZ\r\x00\x00\x00\r\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6\x81\x00\x00\x00\x00sec.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x005\x00\x00\x002\x00\x00\x00\x00\x00'

我使用了第二个,我从检索中得到了相同的字符串。

为了重建zip文件(输出是字符串),我使用代码

plaintext = open("out.zip", "w")
plaintext.write(output)
plaintext.close()

但是当我尝试打开它时,写入的文件已损坏。当我尝试用

读取写入的内容时
output = output.encode(encoding='utf_8', errors='strict')

output = bytes(output, 'utf_8')

输出

b"b'PK\\x03\\x04\\x14\\x00\\x00\\x00\\x00\\x00n\\x8f!K\\\\\\xac\\xdaZ\\r\\x00\\x00\\x00\\r\\x00\\x00\\x00\\x07\\x00\\x00\\x00sec.txt13 byte 1.10mPK\\x01\\x02\\x14\\x00\\x14\\x00\\x00\\x00\\x00\\x00n\\x8f!K\\\\\\xac\\xdaZ\\r\\x00\\x00\\x00\\r\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xb6\\x81\\x00\\x00\\x00\\x00sec.txtPK\\x05\\x06\\x00\\x00\\x00\\x00\\x01\\x00\\x01\\x005\\x00\\x00\\x002\\x00\\x00\\x00\\x00\\x00'"

与源文件不同。

如何忠实地重建嵌入式文件?

1 个答案:

答案 0 :(得分:0)

当您以rb模式读取文件时,您将获得一个字节数组。如果你打印它,它可能看起来像一个字符串,但每个单独的元素实际上是一个整数。

>>> my_bytes = b'hello'
>>> my_bytes
b'hello'
>>> my_bytes[0]
104

这解释了错误

  
    

" C:\ Users \ Sherif \ OneDrive \ Pyhton Projects \ Kivy Tests \ stepic.py",第58行,在encode_imdata中byte = ord(data [i])TypeError:ord()期望的字符串长度为1,但是找到了

  

ord()需要一个字符串,因此您必须将所有字节转换为字符串。不幸的是,str(some_byte_array)并没有按照您的想法行事。它创建了一个字节数组的文字字符串表示形式,包括前面的" b"和周围的报价。

>>> string = str(my_bytes)
>>> string[0]
'b'
>>> string[1]
"'"
>>> string[2]
'h'

您想要的是将每个字节(整数)单独转换为字符串。 map(chr, some_byte_array)会为您完成此操作。我们必须这样做只是因为stepic需要一个字符串。当它嵌入一个字符时,它会ord(data[i]),它将长度为1的字符串转换为它的Unicode代码(整数)。

此外,我们不能将字符串保留为地图对象,因为代码需要在嵌入之前计算整个字符串的长度。因此,''.join(map(chr, some_bytearray))是我们必须用于输入密码的内容。

对于提取步骤则相反。它逐字节提取秘密,并将其转换为chr(byte)的字符串。为了扭转这一点,我们需要单独获得每个字符的序数值。 map(ord, out)应该做到这一点。因为我们想用二进制文件来编写我们的文件,所以进一步将它放到bytearray()中将会处理所有事情。

总的来说,这些是您应该对代码进行的更改。

def enc_():
    im = Image.open("secret.png")
    text = ''.join(map(chr, open("source.zip", "rb").read()))
    im = stepic.encode(im, text)
    im.save('stegolena.png','PNG')

def dec_():
    im1=Image.open('stegolena.png')
    out = stepic.decode(im1)
    plaintext = open("out.zip", "wb")
    plaintext.write(bytearray(map(ord, out)))
    plaintext.close()