3 Steganography means hiding secret [information](information.md) within some unrelated data by embedding it in a way that's very hard to notice; for example it is possible to hide text messages in a digital photograph by slightly modifying the colors of the image pixels -- that photo then looks just like an innocent picture while in fact bearing an extra information for those who know it's there and can read it. Steganography differs from [encryption](encryption.md) by trying to avoid even suspicion of secret communication.
5 There are many uses of steganography, for example in secret communication, bypassing [censorship](censorship.md) or secretly tracking a piece of digital media with an invisible [watermark](watermark.md) (game companies have used steganography to identify which tester's game client was used to leak pre-release footage of their games). [Cicada 3301](cicada.md) has famously used steganography in its puzzles.
7 Steganography may need to take into account the possibility of the data being slightly modified, for example pictures exchanged on the [Internet](internet.md) lose their quality due to repeating [compression](compression.md), cropping and format conversions. Robust methods may be used to preserve the embedded information even in these cases.
9 Some notable methods and practices of steganography include:
11 - Embedding in **text**, e.g. making intentional typos in certain places, using extra white or zero-width characters, modifying formatting and case or using [Unicode](unicode.md) homoglyphs can all carry information.
12 - Embedding in **images**. One of the simplest methods is storing data in least significant bits of pixel values (which won't be noticeable by human eyes). Advanced methods may e.g. modify statistical properties of the image such as its color [histogram](histogram.md).
13 - Embedding in **sound**, **video**, vector graphics and all other kinds of media is possible.
14 - All kinds of data can be embedded given enough storage capacity of given bearing medium (e.g. it is possible to store an image in text, sound in another sound etc.).
15 - Information that's present but normally random or unimportant can be used for embedding, e.g. the specific order of items in a list (its [permutation](premutation.md)) can bear information as well as length of time delays in timed data, amount of noise in data etc.
17 The following two pictures encode text, each picture a different one, written under it. (The method used for the encoding as well as the whole code will be present further below.)
24 '':~:~:::'.,.'.,,-.,+$$Ofls5'
25 .~:~''':::~:;:_::;_.,',,_:s"(!s^x}$;
26 -.~JJ<;.'::;~;;_::_::::_;<+F!v!r{888
27 -.<#O#$$ezrslll)l+lfr}{V$88#$!
28 '~+588#O$8$O8$8#O$#$O5,
31 $@ M$ 8W M$ eFc>!vs:;sJ:/, , -:_!\
32 $@ @8 8@ @# ^esCc+//s^;_^c+cc+cc+cc+cCi
33 88#8 8# 88 #exoCC+cc>^^s^^s^^s^^s^^s//>/c+c/
34 #8 8#88 #VxsFC)CC+cc+cc+cc+//+cc+cc+cc)/
35 8#88 #8Vi^^oFFoFFoFFoFFoF^oFFoFFoFFs
36 8@ W8 8#88 s88#Ve}xxixxiee}ee}eeixxi^^_
37 88#88# 8@- 8@ #8 8#88#88#88#88#88#88#88#x
38 8W @8 #@, #88#8 ,#88#88#88#88#88#88#88)
39 88#8 8W ,8# ,V#88#88#88#88#88#^
48 *The ability of accurate observation is often called cynicism by those who have not got it.*
55 ,,;;;__;~.',...'.,,,+$#$flsV,
56 -~:;.',:~:;;_~::~~:.'.'._~!cls!!x}$;
57 ',;cc/_,,_;;_;;_;;_;;_;;_/co^^sxe#88
58 -,/#88#8eix^)CC)Cc)Fx}eV#88#8^
59 -;cb88#88#88#88#88#88b,
62 8@ W8 8W @8 }Fc>^^s;;sc;>, , -;;s/
63 8W @8 #@ @# ^esCc+//s^;_^c+cc+cc+cc+cCi
64 88#8 8# 88 #exoCC+cc>^^s^^s^^s^^s^^s//>/c+c/
65 #8 8#88 #VxsFC)CC+cc+cc+cc+//+cc+cc+cc)/
66 8#88 #8Vi^^oFFoFFoFFoFFoF^oFFoFFoFFs
67 8@ W8 8#88 s88#Ve}xxixxiee}ee}eeixxi^^_
68 88#88# 8@- 8@ #8 8#88#88#88#88#88#88#88#x
69 8W @8 #@, #88#8 ,#88#88#88#88#88#88#88)
70 88#8 8W ,8# ,V#88#88#88#88#88#^
79 *To be or [not to be](suicide.md). That is the question.*
83 Here is a quite basic [C](c.md) program that hides text in ASCII grayscale pictures (used to generate the examples above):
88 const char alphabet[] = // our 6 bit alphabet, position = code
89 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .";
91 const char groups[] = // newline separated groups of similar brightness chars
92 "@WM0" "\n" "Q&%R" "\n" "8#O$" "\n" "B69g" "\n"
93 "NUmP" "\n" "w3XD" "\n" "Vbp5" "\n" "d24S" "\n"
94 "qkGK" "\n" "EHAZ" "\n" "hY[T" "\n" "e}a{" "\n"
95 "]y17" "\n" "Fofu" "\n" "n?Ij" "\n" "C)(l" "\n"
96 "xizr" "\n" "^sv!" "\n" "t*=L" "\n" "/>\\<" "\n"
97 "c+J\"" "\n" ";_~:" "\n" ",-'." "\n";
99 unsigned char toAlphabet(unsigned char c) // encodes char to 6 bit alphabet
101 for (unsigned char i = 0; i < 64; ++i)
102 if (alphabet[i] == c)
108 unsigned char fromAlphabet(unsigned char c) // decodes char from 6 bit alphabet
110 return alphabet[c & 0x3f];
113 int canEncode(char c) // says if specific visual char can be used for encoding
118 for (int i = 0; i < sizeof(groups) - 1; ++i)
125 const char *seekGroup(char c) // helper, seeks to similar brightness group
127 const char *s = groups;
140 char encode(char c, int n) // encodes value n in given encodable char
142 const char *s = seekGroup(c);
153 int decode(char c) // decodes value n from given encodable char
157 const char *s = seekGroup(c);
168 int main(int argc, char **argv)
170 unsigned char currentChar = 0;
171 int pos = 0, done = 0;
173 while (1) // read all chars from input
182 // decoding text from image
186 currentChar = (currentChar << 2) | decode(c);
190 putchar(fromAlphabet(currentChar));
199 // encoding text into image
203 unsigned char c2 = !done ? argv[1][pos / 3] : 0;
211 c2 = (toAlphabet(c2) >> ((2 - pos % 3) * 2)) & 0x03;
224 The usage is following: make a file with a grayscale [ASCII art](ascii_art.md) picture, then pass it to the standard input of this program along with text you want to encode (maximum length of the text you can encode is given by the count of usable characters in the input image) passed as the first argument to the program, for example: `cat picture.txt | ./program "hello"`. The program will print out the image with the text embedded in. To read the text from the image similarly pass the picture to the program's input, without passing any arguments, for example: `cat picture2.txt | ./program`. The text will be written to terminal.
226 The method used is this: firstly for the encoded message we use our own 6 bit alphabet -- this only allows us to represent 63 symbols (which we have chosen to be uppercase and lowercase letters, space and period) but will allow us to store more of them. Each 6 bit symbol of our alphabet will be encoded by three bit pairs (3 * 2 = 6). One bit pair will be encoded in one ASCII art character by altering that character slightly -- we define groups of ASCII characters that have similar brightness. Each of these groups consists of 4 characters (e.g. `@WM0` is the group of darkest characters), so a character can be used to encode 2 bits (one bit pair of the encoded symbol). The first character in the group encodes `00`, the second one `01` etc. However not all ASCII art characters can be used for encoding, for example space (` `) has no similar brightness characters, so these are just skipped.