Search code examples
cbitwise-operatorsbit-shiftsteganography

What does this bitwise operation perform?


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


Solution

    • 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.