我一直在尝试对一个目录中的多个图像进行隐写术,并使用Stegano模块将它们保存到另一个目录中。
我想出了代码:
from stegano import slsb
import os, sys
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(APP_ROOT, 'current_folder/')
dirs = os.listdir( path )
new_path = os.path.join(APP_ROOT, 'new_folder/')
dirs2 = os.listdir( new_path )
def stegogal():
for item in dirs:
if os.path.isfile(path+item):
sw = "secretword"
f, e = os.path.splitext(path+item+'.png')
secret = slsb.hide(f, sw)
f, e = os.path.splitext(new_path+item+'.png')
secret.save(f + '_G.png')
stegogal()
然而,几乎所有图像中的秘密世界(3个中的2个)都会以某种方式混乱。例如,它会隐藏"secretworg"
而不是"secretword"
。
有人可以向我解释一下这似乎是什么问题,并且可能会有更好的方法来解决这个问题吗?
答案 0 :(得分:3)
嵌入秘密有一个错误。该程序对消息的长度进行编码,以便知道要读取多少位以进行提取。在内部,您的消息变为
message = str(len(message)) + ":" + message
,在您的情况下,是104位。由于这不能被3整除,因此bug会在这里开始
if index + 3 <= len(message_bits):
你只嵌入了前102位。对于提取,程序将读取足够的位来重建消息,但最后2位将受原始图像所具有的任何像素值的支配(你甚至可能没有注意到巧合的问题)。
>>> '{:08b}'.format(ord('d'))
'01100100'
>>> '{:08b}'.format(ord('g'))
'01100111'
>>>
虽然由不同答案发布的快速黑客解决了这个问题,但它通过将其转移到可以忽略的其他地方来实现。修复源代码会更方便(也更正确),这样您就可以方便地导入正确的函数,而无需依赖任何包装补丁。
使用必要数量的0来填充message_bits
以使其长度可被3整除(它们将在提取后被丢弃),
message_bits = "".join(tools.a2bits_list(message))
message_bits += '0' * ((3 - (len(message_bits) % 3)) % 3)
或更改嵌入例程,以便在剩余少于3时不跳过任何位。
for row in range(height):
for col in range(width):
if index + 3 <= len(message_bits):
(r, g, b) = img.getpixel((col, row))
r = tools.setlsb(r, message_bits[index])
g = tools.setlsb(g, message_bits[index+1])
b = tools.setlsb(b, message_bits[index+2])
encoded.putpixel((col, row), (r, g , b))
index += 3
elif index < len(message_bits):
# More bits left, but not enough to embed in r, g and b.
(r, g, b) = img.getpixel((col, row))
r = tools.setlsb(r, message_bits[index])
index += 1
if index < len(message_bits):
g = tools.setlsb(g, message_bits[index])
index += 1
encoded.putpixel((col, row), (r, g , b))
else:
# Embedding is done, no point in iterating over more pixels
return encoded
return encoded
请注意,slsbset
模块中存在相同的错误。
答案 1 :(得分:0)
编辑2:错误修复,提交发布不要再使用解决方案了
**编辑:带有错误修复的新版本
lenght bug
# -*- coding: utf-8 -*-
from stegano import slsb
import os, sys
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(APP_ROOT, 'current_folder/')
dirs = os.listdir( path )
new_path = os.path.join(APP_ROOT, 'new_folder/')
dirs2 = os.listdir( new_path )
def stegogal():
for item in dirs:
if os.path.isfile(path+item):
sw = ur"secretword" + ur" "
f, e = os.path.splitext(path+item+'.png')
secret = slsb.hide(f, sw)
f, e = os.path.splitext(new_path+item+'.png')
secret.save(f + '_G.png')
stegogal()
print(slsb.reveal("secret.png")[:-1])