这个按位运算执行什么?

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。你会注意到其中的区别吗?也许不是。