Update
[less_retarded_wiki.git] / steganography.md
blobfe5dda1feeee732af60fac9f7d290d431fd3e800
1 # Steganography
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.)
19 ```
20                        -,~.',.
21                     '.,,  -.....~.
22                    _..-,   .-.'.,~>"
23                 ,,-.,-.'',,-.!$$r><l+
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,
29                    ,sOO#$O8$8#88#.
30    O8$$                $Opa{a{^x_
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#^
40               8W  88       -C8#88#88#8^-
41                              ,8#8,-^Vie,
42                        _;;oF^#88+c,-cc),
43                         ,>,,      -,/>/,
44                             sCC)c/s^/s,
45                               ,_,,
46 ```
48 *The ability of accurate observation is often called cynicism by those who have not got it.*
50 ```
51                        -,~.,-,
52                     ,-..  '.'.,,_.
53                    ;-'.'   ,,-.,':/+
54                 '.,,,-'.,.,-,^#$r\<("
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,
60                    ,s88#88#88#88#,
61    8#88                #8V}ee}^x_
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#^
71               8W  88       -C8#88#88#8^-
72                              ,8#8,-^Vie,
73                        _;;oF^#88+c,-cc),
74                         ,>,,      -,/>/,
75                             sCC)c/s^/s,
76                               ,_,,
77 ```
79 *To be or [not to be](suicide.md). That is the question.*
81 ## Example Code
83 Here is a quite basic [C](c.md) program that hides text in ASCII grayscale pictures (used to generate the examples above):
85 ```
86 #include <stdio.h>
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)
103       return i;
105   return 63;
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
115   if (c == '\n')
116     return 0;
118   for (int i = 0; i < sizeof(groups) - 1; ++i)
119     if (groups[i] == c)
120       return 1;
122   return 0;
125 const char *seekGroup(char c) // helper, seeks to similar brightness group
127   const char *s = groups;
129   while (c != *s)
130     s++;
132   while (*s != '\n')
133     s++;
135   s--;
137   return s;
140 char encode(char c, int n) // encodes value n in given encodable char
142   const char *s = seekGroup(c);
144   while (n)
145   {
146     s--;
147     n--;
148   }
150   return *s;
153 int decode(char c) // decodes value n from given encodable char
155   int n = 0;
156   
157   const char *s = seekGroup(c);
159   while (*s != c)
160   {
161     s--;
162     n++;
163   }
165   return n;
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
174   {
175     int c = getchar();
177     if (c == EOF)
178       break;
180     if (argc < 2)
181     {
182       // decoding text from image
184       if (canEncode(c))
185       {
186         currentChar = (currentChar << 2) | decode(c);
188         if (pos % 3 == 2)
189         {
190           putchar(fromAlphabet(currentChar));
191           currentChar = 0;
192         }
194         pos++;
195       }
196     }
197     else
198     {
199       // encoding text into image
201       if (canEncode(c))
202       {
203         unsigned char c2 = !done ? argv[1][pos / 3] : 0;
205         if (!c2)
206         {
207           done = 1;
208           c2 = ' ';
209         }
211         c2 = (toAlphabet(c2) >> ((2 - pos % 3) * 2)) & 0x03;
212         c = encode(c,c2);
213         pos++;
214       }
216       putchar(c);
217     }
218   }
220   return 0;
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.