C# source - 20.7 Kb

Introduction

The application described in part 2 always added visible noise to the carrier bitmaps. This article is about splitting the bytes and hiding each bit in a different pixel. The hidden message is really invisible, because only the lowest bit of one color component is changed.

Background

Before reading this, you should have read at least part one, "Steganography - Hiding messages in the Noise of a Picture". This article uses the application described in part one and two, but you don’t need the the features added in part two to understand this one.

End of the Rainbow

Replacing a whole byte of a RGB color produces a rainbow pattern. This is how a white image (all pixels just white) looks like after hiding a text message:

typical colour noise

On a colourful photo these rainbow pixels may be alright.
In grayscale mode the same message in the same picture looks like this:

typical grayscale noise

As you can see, too many bits of the pixels have been changed.
Now we’re going to spread each byte over eight pixels and make the rainbow disappear.

Get and Set Bits

spreading a byte over eight pixels

For each byte of the message we have to

  1. Grab a pixel
  2. Get the first bit of the message byte
  3. Get one colour component of the pixel
  4. Get the first bit from the colour component
  5. If the colour-bit is different from the message-bit, set/reset it
  6. Do the same for the other seven bits

The C#-functions for getting and setting single bits are simple:

private static bool GetBit(byte b, byte position){
        return ((b & (byte)(1 << position)) != 0);
}

private static byte SetBit(byte b, byte position, bool newBitValue){
        byte mask = (byte)(1 << position);
        if(newBitValue){
                return (byte)(b | mask);
        }else{
                return (byte)(b & ~mask);
        }
}

The rest of the code has not changed much. Hiding works like that now...

hide a message

...and extraction works like that:

extract a message

That’s enough text for this page. If you want to know the details, you should download the source.