First of all: what is steganography?
Steganography is the discipline whose purpose is to hide the communication between two people.
Maybe you're wondering what's the difference with criptography (if not go fuck yourself, just kidding): the difference is that while criptography makes the messages between two people not understandable, steganography's purpose is to completly hide the communication.
An example can be: Person A sends to person B a text file about an ordinary topic, but then imagine that in each paragraph of the text there is a number of commas which goes from 0 to 26.
This number could indicate a letter of the alphabet or a "space" (if = 0).
Now, this is a very simple way to send messages and in computer science people exchange lots of data and there are lots of places where you can hide messages (metadata, audio noise, text font etc..).
In this project I'll show you a REALLY simple and rough way to hide an image in another image.
Before going to the code there is an import concept that I'd like to explain: in each byte there are some bit which affect relatively a few the decimal value of the byte.
These bits are called less significant bits (from now I'll refer to them as LSB).
An example: 10010101 = 149
10010100 = 148
so here the Least Significant Bit is this: 10010101 infact here its value affects the decimal number by just one unit.
Now coming back to the idea of steganography in images, for each pixel of an image we have 3 bytes on which we can work: the bytes containing values for red, green and blue colors (and sometimes also for alpha transparency, but I won't talk about this).
Of course the process will work on LSB so the resulting image will be mostly equal to the original (no human eye will notice the difference).
As I said I'll make very simple tutorial so I'll explain you how to hide a binary image (which means with only black and white, NO INTERMEDIATE COLORS) in the blue channel (it's the simplest to work on).
My code has also other limitation due to the fact that I just made a code snippet and not a complete work: the image you want to hide and the "container" image must be of the same size and in .bmp format (I haven't tried other, maybe will work anyway).
Just one more things before the code: to make the program faster I used some bits operation, you want to understand them completly have a look at processing reference for bitwise OR and bitwise AND (maybe also bitshift).
Here is a very simple schematic on how an RGB color variable is stored:
Here is the code:
PImage img, hidden;
int maxw, maxh;
void setup(){
colorMode(RGB, 255);
img = loadImage("img.bmp");
hidden = loadImage("hidden.bmp");
maxw = img.width;
maxh = img.height;
img.loadPixels();
hidden.loadPixels();
}
void draw(){
for(int n = 0; n < maxw*maxh; n++){
if(hidden.pixels[n] == color(255)){
img.pixels[n] = img.pixels[n] | unbinary("000000000000000000000001"); }
else{
img.pixels[n] = img.pixels[n] & unbinary("111111111111111111111110"); }
}
img.save("processed.bmp");
exit();
}
This code, given a "container" image img.bmp and an image to hide(binary) hidden.bmp we'll process them and output to processed.bmp
This final image so contains in the least significant bit of the blue channel a binary image, to extract it you'll have to make another sketch:
PImage img, hidden;
int maxw, maxh;
void setup(){
colorMode(RGB, 255);
img = loadImage("processed.bmp");
maxw = img.width;
maxh = img.height;
img.loadPixels();
hidden = createImage(maxw, maxh, RGB);
hidden.loadPixels();
}
void draw(){
for(int n = 0; n < maxw*maxh; n++){
if((img.pixels[n] & unbinary("000000000000000000000001")) == 0){
hidden.pixels[n] = color(0);
}
else{
hidden.pixels[n] = color(255);
}
}
hidden.save("foundhidden.bmp");
exit();
}
This sketch, given an image (processed with the program above) processed.bmp will extract the hidden image and output it in foundhidden.bmp
Here is a zip with all files: link.
I know it's a really rough sketch but I think it can be useful just to understand some concepts of steganography, if you refine the code (store image in all the channels and use more LSB instead of just one) advise me, I'd be happy to see your work.
Everyone is free to use the code in this post but I'd appreciate if you mention my name.
I hopeyou like this post, if you have any question please comment or send me an email to damianoandre@gmail.com
Bye, Dami