TransWikia.com

What does this bitwise operation perform?

Stack Overflow Asked by Sudhip Nashi on December 16, 2020

I’ve been doing some projects on the side recently, and I’ve been wanting to go into steganography. I looked up a few ways to do it, but one of them I don’t really understand.

(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));

I get part of it, like the & ~0x3 and & ~0x7 zeroing out the last 2 bits on red / green and on the last 3 bits on blue respectively, but what’s really getting me is the file[f] & 0x60, 0x18, and 0x7. file is an array of unsigned chars which were read into from a binary file, and image is a rgb matrix, with each component having 3 unsigned chars for red, green, and blue. This is all in C, by the way. Thanks in advance

3 Answers

  • It replaces the least significant 2 bits of red with bits 6 and 5 of file[f].
  • It replaces the least significant 2 bits of green with bits 4 and 3 of file[f].
  • It replaces the least significant 3 bits of blue with bits 2, 1 and 0 of file[f].

For example

          +---+---+---+---+---+---+---+---+
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 |
          +---+---+---+---+---+---+---+---+

Imagine each color being a combination of three values between 0 and 255 inclusive. White is 255,255,255; Black is 0,0,0; Bright red is 255,0,0; Bright yellow is 255,255,0; etc.

Now imagine we changed replaced the least significant digits of those numbers so that we end up using 252,3,5 instead of 255,0,0. Will you notice the difference? Maybe not.

Correct answer by ikegami on December 16, 2020

The three operations like ... | (file[f] & 0x60) >> 5) mask out bits from file[f], shift them and store them in a color channel. In the first line bit number 5 and 6 (bit number 0 would be the least significant bit) are shifted to the right (... >> 5) and stored in the two lower bits of the red channel. The same is done for bit number 3 and 4 (stored in the two lower bits of the green channel). The three least significant bits (bit number 0, 1 and 2) of file[f] are stored directly in the same bits of the blue channel.

By splitting up the bytes of file like that (while ignoring bit number 8/ the most significant bit) the information is hidden in the color channels of the images while only slightly modifying the color values.

Answered by Stefan Scheller on December 16, 2020

If we take a look at the binary representation of those magic numbers:

0x60 1100000
0x18 0011000
0x7  0000111

we'll see that they are mutually exclusive and add up to 0x7f, i.e. 1111111. So we can use them to mask different bits of the input file and store those parts in different colors. E.g. file[f] & 0x60 >> 5 will give 6th and 7th bits. We lose the 8th bit, but apparently that's intentional.

Answered by bereal on December 16, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP