That photo is the present that I did to Elena. I printed the photo (well, the original photo had a higher resolution), put it on frame and give it to Elena.
So, Why this photo is special? What relation has this photo with the thematic of this blog?. Let me show the magic inside this photo.
That photo is a special photo, ¡inside it the photo hide a message!
If my memory doesn't fail, 4 years ago I develop a little program that can hide texts inside images (bmp's). As usual in me, I had the idea at night and in exams period. That night I forgot all that I had to do and started to develop the program.
What is an image?
An image is a pixel matrix of height*width dimensions, a pixel is a set of bytes that determine the amount of red, green and blue that contain each pixel (each "amount" can be called channel), from now it denote as [red, green, blue], each channel can be anu number between 0 and 255 in decimal, so the red color is [255,0,0] and the white color is [255,255,255], that is, the white color is formed by the presence of all primary colors, this model is called RGB and is frequently used for color representation in light model (as could be monitor of computers), in the other hand, for color representation in paper, the most common model is CMYK. A variation of RGB is ARGB or RGBA, in this model we have a additional channel for alpha.
We center in RGB model that is used in the header image, this image has 8 bit per each channel, this is, 1 byte per each channel (from 0 to 255 in decimal). As I mentioned before a red color in this model is [255, 0, 0]
How can we hide text in an image?
This is simple solution, obviously the solution is hide text inside pixel of the image, but to do this we must ask other question.
What is a text?
A text, same as image or whatever digital thing is a sequence of 1's and 0's. A text is formed by letters and each letter is formed by 8 bits, this is, 1 byte, this is valid for the system that we use in Spain (extended ascii). For example, to write my name, Ángel Luis, the computer understand:
181 110 103 101 108 32 76 117 105 115
If we pass this to binary, that is what computers understand, we obtain:
10110101 01101110 01100111 01100101 01101100 00100000 01001100 01110101 01101001 01110011
How can we hide text in a image? (Again)
What we have to do is try to hide letters of text inside pixels, but we have a limitation, our pixels has 8 bits, the same as a letter, if we store a letter per pixel the image will be distorted because we remove completely a channel of our pixel, so the mos simple way to do our task is store 3 bits per pixel (1 bit per channel), so in order to encode one letter we need 3 pixels. Other thing that we have in mind is that we have to modify the less significant bit in our channel, the purpose of this is to affect as little as possible to our image.For example, if we want encode the letter Á (181, 10110101) in a image completely red that have 3x3 size.Here is the original image in red
If we pass it to binary, we have
Note: For simplicity when a channel is completely 0 we use 00 instead 0000000.
Note: In bold the bits that will be replaced for each of our letter's bits (in that case the letter will be Á, 10110101)
Now, in bold the bits that has been affected by encode.
If we pass it to decimal
As you can see, when we modify the less significant bit we get an error of 1 pixel in each channel respect the original image.
This is our image with the encoded text. Now, we only have to automatize the process via program, have in mind that text must be delimited between start and end flag in order to know where start and end the text.
In the above image we list the current directory where there are 4 files, 2 programs, 1 text and 1 image. Next we show the text inside text_hide (Esto es una prueba de texto oculto en una imagen). Now we run the program codificador, we choose the image where the text will be encode (image1.bmp), the text to hide (text_hide) and the new image that will be generated (image1.bmp). Finally I show that 2 images are different, for that I use a diff command. Despite this, for the human's eye both images are identical.
In above image I show decode process. First I try to decode image.bmp, that is the original image, and the program says that it hasn't hidden text, next I try to decode the file image1.bmp and the program text that it has a hidden text.This method has a disadvantage. If we have a text of 100 letters of length, we need a image of
Not many pixels if we compare it with a high definition photo (1920 x 1090 pixels). But it could be a limitation with little images.
So, this was a special gift to Elena.This technique is called Steganography, and it is based in hide messages inside other containers, in this case, a image.I want to remember you that this program has 4 years old. This program only accepts bmp images of 24 bytes per pixel (8 bytes per channel). If I have to improve this program I considerer the following points
- Accept more images format (like jpg or png), This will be get using some processing image library or framework, for example, imagemagick, Pixmap class from Qt or PixBuf function from GTK+.
- Hide text in a random position in the image, now the text starts encode at position 54.
- Compress the text with well-known, for example Base64.
- Encrypt the text with well-known algorithm (symmetric or asymmetric) like RSA or AES.
- Also hide a text's hash in a random position of the image, with this we can check that message hasn't been modified.