Stegano:在多个图像中嵌入相同的秘密 returns 错误结果

Stegano: embedding the same secret in multiple images returns wrong result

我一直在尝试对一个目录中的多个图像进行隐写术,然后使用 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".

有人可以向我解释一下似乎是什么问题,也许可以提供一些更好的方法吗?

编辑 2:错误已修复,提交版本不再使用下面的解决方案
**编辑:即将修复错误的新版本

长度错误

-- 编码:utf-8 --

# -*- 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])

嵌入秘密时存在错误。该程序对消息的长度进行编码,因此它知道要读取多少位以进行提取。在内部,您的消息变为

message = str(len(message)) + ":" + message

在您的例子中,它是 104 位。由于这不能被 3 整除,所以这里出现错误

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 模块中存在相同的错误。