Skip to content

Instantly share code, notes, and snippets.

@utaal
Created January 4, 2012 01:21
Show Gist options
  • Save utaal/1557933 to your computer and use it in GitHub Desktop.
Save utaal/1557933 to your computer and use it in GitHub Desktop.
steganography: hiding data inside images
inspired by http://blog.wolfram.com/2010/07/08/doing-spy-stuff-with-mathematica/
requires CImg (http://cimg.sourceforge.net/reference/index.html)
#include <iostream>
#include <cstdio>
#include <string>
#include <CImg.h>
using namespace std;
using namespace cimg_library;
typedef CImg<unsigned char> ByteCImg;
void encode(const string& imgFilename, const FILE * input, const string& outputFilename);
void decode(const string& imgFilename, FILE * output);
int main(int argc, char ** argv) {
string cmdname = string(argv[0]);
if (argc > 3 || argc < 2) {
cerr << "usage:" << endl
<< "ENCODE: " << cmdname << " CARRIER_IMAGE OUTPUT_FILENAME < MESSAGE_TO_HIDE" << endl
<< "DECODE: " << cmdname << " IMAGE_WITH_HIDDEN_MESSAGE > EXTRACTED_MESSAGE" << endl;
return 1;
}
if (argc == 3) {
string imgFilename(argv[1]);
cerr << "Embedding in image: " << imgFilename << endl;
string outputFilename(argv[2]);
cerr << "Input from stdin, output to: " << outputFilename << endl;
encode(imgFilename, stdin, outputFilename);
} else {
string imgFilename(argv[1]);
cerr << "Decoding file: " << imgFilename << endl;
decode(imgFilename, stdout);
}
}
void encode(const string& imgFilename, const FILE * input, const string& outputFilename) {
ByteCImg image(imgFilename.c_str());
image &= 0xfe;
ByteCImg::iterator it = image.begin();
for (;;) {
if (feof(stdin)) {
break;
}
char cur = getc(stdin);
for (int b = 0; b < 8; ++b) {
if (it == image.end()) {
break;
}
*it = *it | ((cur >> b) & 0x01);
++it;
}
}
if (it == image.end()) {
cerr << "Cannot fit the entire input in the image" << endl;
}
image.save(outputFilename.c_str());
}
void decode(const string& imgFilename, FILE * output) {
ByteCImg image(imgFilename.c_str());
char * buffer = (char*) malloc(sizeof(char) * image.size());
int bufferpos = 0;
int bit = 0;
char chr = 0;
for (ByteCImg::iterator it = image.begin(); it != image.end(); ++bit, ++it) {
chr |= (*it & 0x01) << bit;
if (bit == 7) {
buffer[bufferpos++] = chr;
// fputc((int) chr, output);
bit = -1;
chr = 0;
}
}
for (; buffer[bufferpos] != EOF; --bufferpos);
for (int i = 0; i < bufferpos; ++i) {
fputc((int) buffer[i], output);
}
}
lsbmessage: lsbmessage.cc
g++ -o lsbmessage lsbmessage.cc -O2 -L/usr/X11R6/lib -lm -lpthread -lX11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment