我最近一直在进行一些项目,并且一直想从事隐写术。我查找了几种方法来做,但是其中一种我不太了解。
(image[i][j].red & ~0x3) | ((file[f] & 0x60) >> 5);
(image[i][j].green & ~0x3) | ((file[f] & 0x18) >> 3);
(image[i][j].blue & ~0x7) | ((file[f] & 0x7));
我得到了一部分,例如&〜0x3和&〜0x7分别将红色/绿色的最后2位和蓝色的最后3位清零,但是真正让我得到的是文件[f]& 0x60、0x18和0x7。 file
是从二进制文件读取的无符号字符数组,而image
是rgb矩阵,每个组件具有3个用于红色,绿色和蓝色的无符号字符。顺便说一下,这一切都在C语言中。预先感谢
答案 0 :(得分:5)
red
的最低有效2位替换为file[f]
的6位和5位。green
的最低有效2位替换为file[f]
的4位和3位。blue
的最低有效3位替换为file[f]
的2、1和0位。例如
+---+---+---+---+---+---+---+---+
file[f] | h | g | f | e | d | c | b | a |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
& 0x60 | 0 | g | f | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
>> 5 | 0 | 0 | 0 | 0 | 0 | 0 | g | f |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
red | H | G | F | E | D | C | B | A |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
& ~0x3 | H | G | F | E | D | C | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
| | H | G | F | E | D | C | g | f |
+---+---+---+---+---+---+---+---+
想象一下每种颜色都是0到255之间(含3和0)的三个值的组合。白色为255,255,255;黑色是0,0,0;鲜红色为255,0,0;亮黄色为255,255,0;等
现在想象我们改变了那些数字的最低有效位,以至于我们最终使用252,3,5而不是255,0,0。您会注意到差异吗?也许不是。
答案 1 :(得分:1)
如果我们看一下这些魔术数字的二进制表示形式:
0x60 1100000
0x18 0011000
0x7 0000111
我们将看到它们是互斥的,并且总计为0x7f
,即1111111
。因此,我们可以使用它们来掩盖输入文件的不同位,并以不同的颜色存储这些部分。例如。 file[f] & 0x60 >> 5
将给出第6位和第7位。我们丢失了第8位,但这显然是故意的。
答案 2 :(得分:1)
... | (file[f] & 0x60) >> 5)
之类的三个操作会屏蔽file[f]
中的位,将它们移位并存储在颜色通道中。在第一行中,第5和6位(第0位为最低有效位)向右(... >> 5
)移位并存储在红色通道的两个较低位中。
对第3位和第4位(存储在绿色通道的两个低位中)进行相同的操作。 file[f]
的三个最低有效位(编号0、1和2)直接存储在蓝色通道的相同位中。
通过像这样file
的字节分割(而忽略第8位/最高有效位),信息隐藏在图像的颜色通道中,而仅稍稍修改颜色值。