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: }