1: // encode -- Steganographically encode a message into a fax image. 4: #include <iostream.h> 5: #include <fstream.h> 6: #include <sys/stat.h> 7: #include <stdlib.h> 8: #include <stdio.h> 10: #include "bit_array.H" 11: #include "permuted_sample.H" 14: // Calling Sequence: 15: // 16: // stegafax encode <seed> <ciphertext_file> <raster_file> <stega_file> 17: // 18: int encode(int nargs, char* args[]) { 20: // Get the parameters. 22: if (nargs != 6) return -1; // check number of parameters 23: 24: char* SEED = args[2]; 25: char* CIPHERTEXT = args[3]; 26: char* RASTER_FILE = args[4]; 27: char* STEGA_FILE = args[5]; 29: // Read in the fax raster. 31: ifstream raster_file(RASTER_FILE); 32: raster_file.ignore(3); // trash the raster's magic number 33: long rows; // number of rows in raster 34: raster_file >> rows; // get number of rows from pbm file 35: long cols; // number of collums in raster 36: raster_file >> cols; // get number of cols from pbm file 37: raster_file.ignore(1); // discard terminal newline 38: long npixels = rows*cols; // number of pixels in raster 39: long nbytes = (npixels + 7)/8; // number of bytes in raster 40: bit_array raster(rows, cols); // make a bit array to hold the pbm raster 41: raster_file.read(raster.bytes, nbytes); // read the pbm raster file into it 43: // Read in the ciphertext. 45: struct stat statbfr; // get length of ciphertext file 46: stat(CIPHERTEXT, &statbfr); 47: long ciphertext_bytes = statbfr.st_size; 48: long ciphertext_length = 8*ciphertext_bytes; 50: ifstream ciphertext_file(CIPHERTEXT); // open the ciphertext file 51: bit_array ciphertext(ciphertext_length); // make a bit array to hold it 52: ciphertext_file.read(ciphertext.bytes, ciphertext_length); // then read the ciphertext into it 54: // Stuff cyphertext length as last 32 bits in the raster. 56: long len; 57: long i; 58: for (len = ciphertext_length, 59: i = 1; 60: i <= 32; 61: len /= 2, 62: i++) { 63: raster.set(npixels - i, len % 2); 64: } 66: // Instantiate a random number generator. 68: int seed = atoi(SEED); 69: prng rand(seed); 71: // Generate the spots where the ciphertext will be mingled. 73: permuted_sample spot(rand, ciphertext_length, npixels - 32); // reserve last 32 bits for cyphertext length 75: // Mingle the ciphertext into the raster. 77: for (i = 0; i < ciphertext_length; i++ ) { 78: raster.set(spot(i), ciphertext(i)); // stuff the ciphertext bit in place of the pixel 79: } 81: // Output the stegafax raster. 83: ofstream stega_file(STEGA_FILE); 84: stega_file << "P4\n"; // pbm magic number 85: stega_file << rows << " " << cols << "\n";; 86: stega_file.write(raster.bytes, nbytes); // output stegafax raster 88: return 0; 89: }