从字符串输出重建源文件
Reconstruct the source file from string output
我用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()
我收到错误
Complete Trace back
Traceback (most recent call last):
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\simple.py", line 28, in enc_()
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\simple.py", line 8, in enc_
im = stepic.encode(im, text)
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 89, in encode
encode_inplace(image, data)
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 75, in encode_inplace
for pixel in encode_imdata(image.getdata(), data):
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 58, in encode_imdata
byte = ord(data[i])
TypeError: ord() expected string of length 1, but int found
有两种方法可以转换为字符串。
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'"
与源文件不同
忠实地重建嵌入文件需要什么?
当您以 rb
模式读取文件时,您将获得一个字节数组。如果打印它,它可能看起来像一个字符串,但每个单独的元素实际上都是一个整数。
>>> my_bytes = b'hello'
>>> my_bytes
b'hello'
>>> my_bytes[0]
104
这里解释错误
"C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 58, in encode_imdata byte = ord(data[i]) TypeError: ord() expected string of length 1, but int found
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()
我用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()
我收到错误
Complete Trace back
Traceback (most recent call last):
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\simple.py", line 28, in enc_()
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\simple.py", line 8, in enc_
im = stepic.encode(im, text)
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 89, in encode
encode_inplace(image, data)
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 75, in encode_inplace
for pixel in encode_imdata(image.getdata(), data):
File "C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 58, in encode_imdata
byte = ord(data[i])
TypeError: ord() expected string of length 1, but int found
有两种方法可以转换为字符串。
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'"
与源文件不同
忠实地重建嵌入文件需要什么?
当您以 rb
模式读取文件时,您将获得一个字节数组。如果打印它,它可能看起来像一个字符串,但每个单独的元素实际上都是一个整数。
>>> my_bytes = b'hello'
>>> my_bytes
b'hello'
>>> my_bytes[0]
104
这里解释错误
"C:\Users\Sherif\OneDrive\Pyhton Projects\Kivy Tests\stepic.py", line 58, in encode_imdata byte = ord(data[i]) TypeError: ord() expected string of length 1, but int found
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()