Blog RSS Feed Patreon: ViGreyTech GitHub: ViGrey Twitter: @ViGreyTech LinkedIn: Vi Grey

Encoding Information into Images

Apr 17, 2017

Steganography is the practice of hiding information within other information. This is quite often done with a message inside of an image or inside of music. With steganography, we can use images to send messages in plain sight.

Images are made of pixels that have 4 values, the red, blue, and green levels and the opacity. There are 256 possible values, 00 through FF, for each of the color levels and for the opacity. Because we don't want our image to be partially transparent, we are going to keep the opacity value of all of the pixels at FF. For this example, we'll use my recent profile picture as a source image, which can be seen below.

Source image to encode a message into

Let's say we have a simple message of Hello World! that we would like to encode into those pixels. Hello World! has the hexadecimal value of 48 65 6C 6C 6F 20 57 6F 72 6C 64 21, so we only need 12 bytes to encode the information. We can't just use those values as red, green, and blue color values, as that would modify the original image too much. We'll need to be a little more clever and keep the image looking close to the original.

256 values (8 bits) of information for each color is more than we need for each pixel, so for this example, we will use the last 4 bits of each value to encode the information. With a red, blue, and green color value, that gives us 12 bits (1.5 bytes) of information, so 2 pixels can hide 3 bytes of information. A 12 bytes long message would only need 8 pixels. That means, for our image, we can just use the first 8 pixels, which can be seen below.

Original 8 pixels before encoding the message "Hello World!"

Now let's actually encode the message Hello World! into those 8 pixels. Because we only need the last 4 bits of each color value for each pixel, we are going to leave the first 4 bits alone and only set the last 4 bits. With the hexadecimal value of 48 65 6C 6C 6F 20 57 6F 72 6C 64 21, the red value of the first pixel can store the first half of the first byte, so we change BF to B4. The green value of the first pixel can store the second half of the first byte, so we change E9 to E8, so now we have the first byte of the message, 48, encoded. We continue with the blue value of the pixel, then the red value of the next pixel, and so on so forth. The result of encoding the message into the pixels is shown below.

New 8 pixels with the encoded message "Hello World!"

Congrats! We just encoded Hello World! into an image! If someone wanted to read the message, they'd just grab the second half of each color value in each pixel. As you can see, the color values of each pixel did not change by much, but if you wanted the colors to change even less, you could use fewer bits from each color value of each pixel, but that would also require more pixels to encode a message. If we only took the last 2 bits of each color value instead of 4 bits, it would take 16 pixels to encode Hello World!, but the color values of each pixel wouldn't change as much.

There are many steganographic systems that do a better job at hiding information and avoiding detection. This steganographic system was just an example. A list of steganography programs can be found at http://www.jjtc.com/Steganography/tools.html.