manual.html
cf8528631089502e2d8f34178122bb331c2329170ca78b743b65caadf076299b
<HTML>
<HEAD><TITLE>The gifshuffle manual page</TITLE></HEAD>
<BODY BGCOLOR="#8c8c8c" LINK="#c84848" VLINK="#903030">
<CENTER><H1>The gifshuffle steganography program</H1></CENTER>
<H3>Synopsis</H3>
<DL>
<DD> <B>gifshuffle</B> [ <B>-CQS</B> ] [ <B>-p</B> <I>passwd</I> ]
[ <B>-f</B> <I>file</I> | <B>-m</B> <I>message</I> ]
[ <I>infile.gif</I> [ <I>outfile.gif</I> ]]
</DL>
<H3>Description</H3>
<P>
<B>gifshuffle</B> is a program for concealing messages in GIF images
by shuffling the colourmap. A shuffled image is visibly indistinguishable
from the original. <B>gifshuffle</B> works with all GIF images, including
those with transparency and animation. </P>
<P>
Consider a pack of 52 cards. There are 52 factorial ways to sort the pack,
which means that any particular ordering of the cards can represent a
number in the range [0, 52!-1]. In other words, given <I>n</I> cards,
you can store approximately log<SUB>2</SUB>(<I>n</I>!) bits of information
based on their ordering. </P>
<P>
GIF images contain a colourmap with up to 256 entries, resulting in a
maximum storage capacity of 1675 bits. The image itself consists of a
compressed array of indices into this colourmap. To conceal a message
within a GIF image the following steps take place. </P>
<OL>
<LI> Start with the message you want to conceal, specified on the
command line or in a file. Optionally compress and/or encrypt
this message. You are then left with a sequence of <B>1</B>'s
and <B>0</B>'s.
<LI> Prepend a <B>1</B> to this sequence, giving you a binary number
<I>m</I> (probably quite large).
<LI> Next take a look at the GIF image that you want to conceal the
message in. Count the number of unique colours in the image, and
call the value <I>n</I>. If <I>m</I> > <I>n</I>!-1 then the message
is too large, and the procedure will be aborted.
<LI> The colours in the colourmap are first sorted into their "natural"
order. Each RGB colour is assigned the value (<I>red</I> * 65536 +
<I>green</I> * 256 + <I>blue</I>), and the colours are sorted
according to these values. Any duplicate colours are stored at the
top of the colourmap, and are not used for storing the hidden message.
<LI> Iterate <I>i</I> through the values 1 .. <I>n</I>. Each colour
<I>n</I>-<I>i</I> is allocated a target position (<I>m</I> mod
<I>i</I>), then <I>m</I> is divided by <I>i</I>.
<LI> Each colour (<I>n</I>-1) .. 0 is then in turn inserted into a new
colourmap at its target position. Colours previously occupying the
target position and above are moved up one place.
<LI> The image component of the GIF is then uncompressed, the colour
indices are re-mapped to the new colourmap, and the image is
re-compressed. For animated GIFs this is repeated for each image.
</OL>
<P>
Extracting a hidden message follows a similar procedure, but in reverse.
The ordering of the colourmap is used to construct a binary number,
which is then optionally decrypted and uncompressed before being output. </P>
<P>
<B>gifshuffle</B> provides rudimentary compression, using Huffman tables
optimised for English text. However, if the data is not text, or if
there is a lot of data, the use of the built-in compression is not
recommended, since an external compression program such as
<B>compress</B> or <B>gzip</B> will do a much better job. </P>
<P>
Encryption is also provided, using the
<A HREF="../ice/index.html">ICE</A> encryption algorithm
in 1-bit cipher-feedback (CFB) mode. Because of ICE's arbitrary
key size, passwords of any length up to 1170 characters are supported
(since only 7 bits of each character are used, keys up to 1024-bytes
are supported). </P>
<P>
If a message string or message file are specified on the command-line,
<B>gifshuffle</B> will attempt to conceal the message in the file
<I>infile.gif</I> if specified, or standard input otherwise.
The resulting file will be written to <I>outfile.gif</I> if specified,
or standard output if not. </P>
<P>
If no message string is provided, <B>gifshuffle</B> attempts to extract a
message from the input file. The result is written to the output file
or standard output. </P>
<H3>Options</H3>
<DL>
<DT> <B>-C</B>
<DD> Compress the data if concealing, or uncompress it if extracting.
<BR><BR>
<DT> <B>-Q</B>
<DD> Quiet mode. If not set, the program reports statistics such as
compression percentages and amount of available storage space used.
<BR><BR>
<DT> <B>-S</B>
<DD> Report on the amount of space available for hidden message in the
GIF colourmap. This is calculated from the number of unique colours
in the image.
<BR><BR>
<DT> <B>-p</B> <I>password</I>
<DD> If this is set, the data will be encrypted with this password during
concealment, or decrypted during extraction.
<BR><BR>
<DT> <B>-f</B> <I>message-file</I>
<DD> The contents of this file will be concealed in the input GIF image.
<BR><BR>
<DT> <B>-m</B> <I>message-string</I>
<DD> The contents of this string will be concealed in the input GIF image.
Note that, unless a newline is somehow included in the string, a newline
will not be printed when the message is extracted.
</DL>
<H3>Examples</H3>
<P>
The following command will conceal the message "Meet me at 6" in the
file <I>infile.gif</I>, with compression, and encrypted with the password
"hello world". The resulting text will be stored in <I>outfile.gif</I>. </P>
<DL>
<DD> <CODE> gifshuffle -C -m "Meet me at 6" -p "hello world" infile.gif
outfile.gif </CODE>
</DL>
<P>
To extract the message, the command would be </P>
<DL>
<DD> <CODE> gifshuffle -C -p "hello world" outfile.gif </CODE>
</DL>
<P>
Note that the resulting message will not be terminated by a newline. </P>
<P>
The approximate storage capacity of a file can be determined with
the <B>-S</B> option. </P>
<DL>
<DD> <CODE> gifshuffle -S infile.gif </CODE>
</DL>
<HR>
<DIV ALIGN=RIGHT>
<FONT SIZE=-1>
Document last modified by Matthew Kwan, 10 May 1998 <BR>
Please send any comments or corrections to
<A HREF="mailto:mkwan@darkside.com.au">mkwan@darkside.com.au</A>
</FONT>
</DIV>
</BODY>
</HTML>