【问题标题】:Reconstruct the source file from string output从字符串输出重构源文件
【发布时间】:2018-02-20 06:12:58
【问题描述】:

我使用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 行,编码
编码就地(图像,数据)
文件“C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py”,第 75 行,位于 encode_inplace
对于 encode_imdata(image.getdata(), data) 中的像素:
文件“C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py”,第 58 行,位于 encode_imdata
字节 = ord(数据[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'"

与源文件不同。

我必须如何忠实地重建嵌入的文件?

【问题讨论】:

  • 请发布完整的回溯。
  • 我编辑了问题,有完整的回溯
  • 请注意。 Stepic 尚未针对 python 3 进行适当调整。ord() 和 chr() 的工作方式与 python 2 不同,这是因为前者引入了字节和字符串之间的区别。正如我的回答所证明的,这在我们必须经历的体操中很明显,以便在 python 3 中获得所需的结果。取消ord() 和chr() 并只使用字节会更自然。更令人担忧的是,在 python 3 中使用这些函数可能会得到错误的结果。ord('€') = 8364,而程序每个字符只嵌入一个字节。

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


【解决方案1】:

当您以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() expected string of length 1,但是int找到了

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)) 是我们必须使用的输入密码。

提取 stepic 则相反。它逐字节提取秘密并将它们转换为带有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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 2019-06-09
    • 1970-01-01
    相关资源
    最近更新 更多