【问题标题】:Understanding image steganography by LSB substitution method通过 LSB 替换法理解图像隐写术
【发布时间】:2018-09-13 06:50:11
【问题描述】:

我很难理解第 2 节中给出的LSB based steganography 方法。互联网上的示例非常混乱和不清楚。我正在关注 Matlab 实现 https://www.mathworks.com/matlabcentral/fileexchange/41326-steganography-using-lsb-substitution 和题为“使用 LSB 替代的图像隐写术的调查”的论文 TECHNIQUE》下载链接(https://irjet.net/archives/V4/i5/IRJET-V4I566.pdf)

本文的第 5 节给出了基于 LSB 的方法的示例。假设P1 = [10011011], P2 = [01101010], P3 = [11001100] 是要嵌入消息M = [011] 的封面图像的3 个字节。嵌入的结果是P1 = [10011010], P2 = [01101011], P3 = [11001101]

我不知道这个答案是怎么来的。有人可以帮忙给出步骤/工作示例来清除这个概念吗?

根据我对 Matlab 代码的理解, Stego = uint8(round(bitor(bitand(x, bitcmp(2^n - 1, 8)) , bitshift(y, n - 8))));

如果n 是要替换的位数,则通过对封面图像的n 位组(x 变量)进行补码/比较来替换n 位组使用消息的n 位(y 变量)。如果位相同,则不替换,否则交换位。不知道我的理解对不对。

【问题讨论】:

  • 这真的很简单。您从原始图像中的 3 个字节数据开始:P=[10011011, 01101010, 11001100]。这些字节的最低有效位是 100。在 LSB 隐写术中,这些最低有效位被替换为您要隐藏的信息,在本例中为 011。所以原来的3个字节变成了[10011010, 01101011, 11001101]。就是这样。
  • 感谢您的评论。根据 Matlab 代码,命令 2^n 会替换 k = 2^n LSB 位吗?如果n = 4 那么会有2^4 组合并且第4个LSB会被替换吗?这是实际的算法。感谢您的帮助。

标签: algorithm matlab image-processing steganography


【解决方案1】:

您的困惑源于您正在查看的所有 3 个来源都在谈论不同的内容。

论文 2,第 5 节

这描述了 LSB 像素替换隐写术的最基本形式。每个像素由 8 位描述。对于每个像素,我们清除 LSB 并用一位秘密消息替换它。例如,

pixels = [xxxxxxxa, xxxxxxxb]
message = [c, d]
stego_pixels = [xxxxxxxc, xxxxxxxd]

xabcd 是位,我们不在乎 x 是什么。

论文 1,第 2 节

这是 LSB 像素替换隐写术的广义形式。不是将秘密嵌入到 LSB 中,而是将其嵌入到 k-most LSB 中。如果k = 1,那么我们有上面描述的简单形式。数学方程是本节的意思如下:

  1. 我们有一个大小为 MxN 的图像,每个像素的值介于 0 到 255(8 位)之间。
  2. 我们有一个 n 位消息,每个位是 0 或 1。例如,对于 12 位,它应该是 m = [a, b, c, d, e, f, g, h, i, j, k, l]
  3. 由于我们将在每个像素中嵌入 k 位,因此我们将消息位分组为 k 组。假设k = 3,则m' = [abc, def, ghi, jkl]。显然,每个组的值可以在 0 到 2^k - 1 之间。此外,m' 中的组数不能超过我们图像的大小,否则我们将无法嵌入整个消息。李>
  4. 我们清除每个像素的最后 k 位,并用一组m' 替换它们。当你用 2^k 取一个数的模时,你得到的余数是原始数的最后 k 位。因此,通过减去它们,我们清除了最后 k 位。
  5. 与上一步类似,如果我们想提取消息,我们将每个像素与 2^k 取模得到最后 k 位,我们将消息嵌入其中。将这些位组拼接起来并得到原始消息m,返回是很简单的。

Matlab 代码

此代码将大小为 MxN 的图像隐藏到相同大小的封面图像中。这里的想法是 MSB 拥有关于图像的最多信息,而 LSB 最少。比如这是this image的位平面分解。

如果我们决定从秘密图像中隐藏 k 位,我们希望那些是 k 个最高有效位。同样,我们可以将它们隐藏在封面图像的 k 个最低有效位中。 k 值越大,为了更忠实的重建,你会隐藏更多的位元,但是你会引入更多的失真。

让我们分解代码中的嵌套函数,看看它们做了什么。我将使用k 而不是n 来保持与上述部分的一致性。

bitcmp(2^k - 1, 8) 为 8 位创建 2^k - 1 的补码。例如,如果 k = 3,那么 2^k - 1 就像具有位 00000111 并且显然它的补码是 11111000。我们将使用这个数字作为掩码,所以mask = bitcmp(2^k - 1, 8)

bitand(x, mask) 将封面图像的最后 k 位清零,x。这就是bitwise AND operation,我们称第二部分为掩码的原因是因为在任何有 1 的地方,我们都会保留原始位,而在有 0 的地方,我们会得到 0。让我们调用 cleared_pixels = bitand(x, mask)

bitshift(y, 8 - k) 只保留秘密的 k 个最高有效位。例如,对于 k = 3,我们得到abcxxxxx -> 00000abc。这是通过将数字 5 位向右移动来完成的。这是logical shift operation。我们将此结果称为secret = bitshift(y, 8 - k)

最后,bitor(cleared_pixels, secret) 简单地将两者结合在一起。被清除的像素,最后的k位被清除,秘密最多为k位,所以两部分不交互;我们得到了一个纯粹的组合。

【讨论】:

  • 感谢您的回答。根据对 Matlab 代码的解释,这个想法似乎更倾向于第一种技术 - 在论文 2,第 5 节中描述。​​是这样吗?
  • @RiaGeorge 这有点特殊,无论您选择什么 k,秘密始终是封面图像的大小。这是一个结果或编写一个简单的单线,当操作应用于相同大小的矩阵时,它利用了 Matlab 的矢量化。而你最终嵌入的秘密,虽然是无损提取的,但它只是原始秘密的有损表示。
  • @RiaGeorge 考虑到它的有损性,代码中使用的算法效率非常低。将图像加载到像素数组中就像尝试嵌入 bmp 文件一样,非常庞大。即使 k = 1,最终结果也是一个非常松散的秘密近似值。但是,如果您加载 png 或 jpg 文件的原始二进制数据,您应该能够仅使用 k = 1 嵌入整个文件,或者与论文 2 所描述的差不多。
  • 感谢您的回答。 Matlab 代码在k=1 时提取隐藏图像的结果很差。提取的隐藏图像是有损的,原始图像和提取的图像之间的 MSE 非常高。如果您可以提供更好的改进方式来处理代码,那将是非常棒的。如果需要,我可以发布一个新问题。 (抱歉,我现在无法通过手机为答案投票)
猜你喜欢
  • 2016-08-18
  • 2016-05-25
  • 2018-08-01
  • 2021-10-07
  • 2018-10-02
  • 2013-08-18
  • 2011-02-17
  • 2018-07-29
相关资源
最近更新 更多