这个按位运算执行什么?
What does this bitwise operation perform?
最近一直在兼职做一些项目,一直想搞隐写术。我查了几种方法,但其中一种我不太明白。
(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 中。提前致谢
如果我们看一下这些幻数的二进制表示:
0x60 1100000
0x18 0011000
0x7 0000111
我们将看到它们是互斥的并且加起来为 0x7f
,即 1111111
。所以我们可以使用它们来屏蔽输入文件的不同位,并以不同的颜色存储这些部分。例如。 file[f] & 0x60 >> 5
将给出第 6 位和第 7 位。我们丢失了第 8 位,但显然这是故意的。
像... | (file[f] & 0x60) >> 5)
这样的三个操作屏蔽掉file[f]
中的位,移动它们并将它们存储在颜色通道中。在第一行中,第 5 位和第 6 位(第 0 位是最低有效位)向右移动 (... >> 5
) 并存储在红色通道的两个较低位中。
对于第 3 位和第 4 位(存储在绿色通道的两个较低位中)也是如此。 file[f]
的三个最低有效位(位编号 0、1 和 2)直接存储在蓝色通道的相同位中。
通过像这样拆分 file
的字节(同时忽略第 8 位/最高有效位),信息隐藏在图像的颜色通道中,同时仅略微修改颜色值。
- 它将
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 之间的三个值的组合。白棋是 255,255,255;黑色为 0,0,0;鲜红色为 255,0,0;亮黄色为255,255,0;等等
现在想象一下,我们更改了这些数字的最低有效位,以便我们最终使用 252,3,5 而不是 255,0,0。你会注意到其中的区别吗?也许不是。
最近一直在兼职做一些项目,一直想搞隐写术。我查了几种方法,但其中一种我不太明白。
(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 中。提前致谢
如果我们看一下这些幻数的二进制表示:
0x60 1100000
0x18 0011000
0x7 0000111
我们将看到它们是互斥的并且加起来为 0x7f
,即 1111111
。所以我们可以使用它们来屏蔽输入文件的不同位,并以不同的颜色存储这些部分。例如。 file[f] & 0x60 >> 5
将给出第 6 位和第 7 位。我们丢失了第 8 位,但显然这是故意的。
像... | (file[f] & 0x60) >> 5)
这样的三个操作屏蔽掉file[f]
中的位,移动它们并将它们存储在颜色通道中。在第一行中,第 5 位和第 6 位(第 0 位是最低有效位)向右移动 (... >> 5
) 并存储在红色通道的两个较低位中。
对于第 3 位和第 4 位(存储在绿色通道的两个较低位中)也是如此。 file[f]
的三个最低有效位(位编号 0、1 和 2)直接存储在蓝色通道的相同位中。
通过像这样拆分 file
的字节(同时忽略第 8 位/最高有效位),信息隐藏在图像的颜色通道中,同时仅略微修改颜色值。
- 它将
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 之间的三个值的组合。白棋是 255,255,255;黑色为 0,0,0;鲜红色为 255,0,0;亮黄色为255,255,0;等等
现在想象一下,我们更改了这些数字的最低有效位,以便我们最终使用 252,3,5 而不是 255,0,0。你会注意到其中的区别吗?也许不是。