Introduction: This PNG Is Secret Compartment

About: I write software and do other stuff too.

Your challenge, dear reader, is to figure out what message is hidden in
the output.png image that I've put on github for you. You can use the MessageHider code there to extract the message. If you're confused, please comment below and I'll help you get the answer! You can even stop reading right now, just go to github, get the code, and start doing steganography. Enough said, but please stick around and I'll tell you more.

The two pictures here look identical but they are not These are the greenman.png and output.png images I linked above. One of the images is just a boring picture of a green man. The other contains a message, hidden in the pixels of the image.

This instructable is inspired by a great youtube video. After watching this video late at night one day and struggling to think of a cool lecture and midterm exam for an advanced Java programming class, this project was born. The images above, along with the code described in this instructable, are free on Github.

Supplies

You'll need a computer and you'll have to know how to compile and run a Java program. This program is just two short files and you'll need to run it on the command line.

Step 1: What Is Steganography

You should watch the youtube video I linked in the previous step, but here is the summary:

If you need to hide a secret message to a friend, a cool way to do it
is with Steganography. The idea of image Steganography is simple; computer images are made of pixels, and each pixel is a combination of red, green, and blue. In many computer image formats the amounts of red, green, and blue in each pixel are expressed as values from 0-127. So, for example, a very red pixel would have a red value of 127 and green and blue values of zero. The trick is this: a red intensity of 126 is indistinguisable from a red intensity of 127 ( to a human eye ). And so by fiddling with plus or minus one in each red pixel we can hide bits in pixels. If we find a sneaky way to gather the bits back up, we can retrieve the data that we snuck into the image!

Be creative! Steganography can be done with any digital media! You can play with bits in music or video files for example, but that requires you to go do more research outside of the scope of this instructable.

Step 2: How Text Is Encoded on Computers

What follows here might require a degree in CS or alot of hobbyist passion to understand. Computers store data in bits as 1s and 0s. These 1s and 0s are typically grouped in bunches of 8 and referred to as "bytes". As explained here and here there are few ways we can tell a computer to interpret bytes as text. To get the most out of this steganography lecture/instructable you need to more or less understand ASCII and UTF8. These are two common ways to encode language data in a series of bytes.

Once you've got an idea about this topic you'll understand this:
In ASCII and UTF8 the word "the" is represented by the following bytes ( in hex ) 0x74 0x68 0x65. In binary, these bytes are: 01110100b 01101000b 01101101b

Furthermore, you'll understand that in UTF8 a Grinning Face Emoji is represented by the following bytes (in hex) 0xF0 0x9F 0x98 0x80. In binary these bytes are 11110000b 10011111b 10011000b 10000000b.

In any event you will see in the attached screenshot that my computer is doing something with these bytes. I've highlighted them in the program output with arrows and a big "LOOK!".

Step 3: How the Program Works

Compiling the program from github is easy. Get the repo shown on the front page here and then

The program is run like this from the command line:

java Main input.png "message I want to hide"

in the attached examples you'll see that I've run

java Main greenman.png "hello world of steganography"

You will do the same thing.

If you look at Main.java you will see that this is what happens:

  1. The program reads the image into a 2D array
  2. The program turns the message you supplied into a byte array ( byte[] )
  3. The program then uses a MessageHider class to hide the message bytes in the image array.
  4. The program then writes the image 2d array out to a file ( output.png ) with the hidden data inside. If you look at this image it is indistinguishable from the original
  5. The program then reads output.png into a new 2D array and uses the extractMessage() function to extract the last bit from as many bytes as you request. These bits will be printed to the screen in bunches of 8s so you can see the binary representation of what data is hidden.
So pretty much the code works as we expect.

Step 4: Conclusion

So I've given you some working code, proof that it works in the form of an image, and some lecture notes I give to my university students. I also gave you a challenge! I spent a few hours writing the code and preparing lecture notes so I'm sorry this instructable doesn't have many pictures. If you think steganography is interesting please accept my challenge!