Initial commit
[keepassx] / src / apg / convert.c
1 /*
2 ** Copyright (c) 1999, 2000, 2001, 2002, 2003
3 ** Adel I. Mirzazhanov. All rights reserved
4 **
5 ** Redistribution and use in source and binary forms, with or without
6 ** modification, are permitted provided that the following conditions
7 ** are met:
8 ** 
9 **     1.Redistributions of source code must retain the above copyright notice,
10 **       this list of conditions and the following disclaimer. 
11 **     2.Redistributions in binary form must reproduce the above copyright
12 **       notice, this list of conditions and the following disclaimer in the
13 **       documentation and/or other materials provided with the distribution. 
14 **     3.The name of the author may not be used to endorse or promote products
15 **       derived from this software without specific prior written permission. 
16 **                
17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND ANY EXPRESS
18 ** OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO, THE IMPLIED
19 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ** ARE DISCLAIMED.  IN  NO  EVENT  SHALL THE AUTHOR BE LIABLE FOR ANY
21 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
23 ** GOODS OR SERVICES;  LOSS OF USE,  DATA,  OR  PROFITS;  OR BUSINESS
24 ** INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY OF LIABILITY,
25 ** WHETHER  IN  CONTRACT,   STRICT   LIABILITY,  OR  TORT  (INCLUDING
26 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 #include "random.h"
35
36 #include "randpass.h"
37 #include "convert.h"
38
39 /*
40 ** GLOBALS
41 */
42
43 /* small letters */
44 char let[26] =
45  {
46  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
47  'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
48  'u', 'v', 'w', 'x', 'w', 'z'
49  };
50 /* capital letters */
51 char clet[26] =
52  {
53  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
54  'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
55  'U', 'V', 'W', 'X', 'W', 'Z'
56   };
57
58 /*
59 ** FUNCTIONS
60 */
61
62 /*
63 ** decapitalize() - This routine replaces all capital letters
64 **                  to small letters in the word:
65 ** INPUT:
66 **   char * - word.
67 ** OUTPUT:
68 **   none.
69 ** NOTES:
70 **   none.
71 */
72 void
73 decapitalize (char *word)
74 {
75  int i = 0; /* counter */
76  int j = 0; /* counter */
77  int str_len = strlen(word);
78  for(j = 0; j < str_len; j++)
79   for(i=0; i < 26; i++)
80    if(word[j] == clet[i])
81        word[j] = let[i];
82 }
83
84 #ifndef APGBFM
85 /*
86 ** capitalize() - This routine designed to modify sullable like this:
87 ** adel ----> Adel
88 ** dot  ----> Dot
89 ** etc.
90 ** INPUT:
91 **   char * - syllable.
92 ** OUTPUT:
93 **   none.
94 ** NOTES:
95 **   none.
96 */
97 void
98 capitalize (char *syllable)
99 {
100  char tmp = 0x00;
101  int i = 0;
102  if ( randint(2) == TRUE)
103   {
104    (void)memcpy((void *)&tmp, (void *)syllable, sizeof(tmp));
105    for(i=0; i < 26; i++)
106      if ( let[i] == tmp )
107        if (is_restricted_symbol(clet[i]) != TRUE)
108          (void)memcpy ((void *)syllable, (void *)&clet[i], 1);
109   }
110 }
111
112 /*
113 ** numerize() - This routine designed to modify single-letter
114 ** syllable like this:
115 ** a ----> 1 or 2 or 3 etc.
116 ** u ----> 1 or 2 or 3 etc.
117 ** etc.
118 ** INPUT:
119 **   char * - single-letter syllable
120 ** OUTPUT:
121 **   none.
122 ** NOTES:
123 **   none.
124 */
125 void
126 numerize (char *syllable)
127 {
128  char *tmp;
129  if ( (tmp = (char *)calloc(1, 4)) == NULL)
130     perror("calloc");
131  if ( strlen (syllable) == 1 )
132       {
133        (void) gen_rand_symbol(tmp, S_NB);
134        (void)memcpy ((void *)syllable, (void *)tmp, 1);
135       }
136  free ((void *)tmp);
137 }
138 /*
139 ** specialize() - This routine designed to modify single-letter syllable
140 ** like this:
141 ** a ----> # or $ or % etc.
142 ** u ----> # or $ or % etc.
143 ** etc.
144 ** INPUT:
145 **   char * - single-letter syllable.
146 ** OUTPUT:
147 **   none.
148 ** NOTES:
149 **   none.
150 */
151 void
152 specialize (char *syllable)
153 {
154  char *tmp;
155  if ( (tmp = (char *)calloc(1, 4)) == NULL)
156     perror("calloc");
157  if ( strlen (syllable) == 1 )
158       {
159        (void) gen_rand_symbol(tmp, S_SS);
160        (void)memcpy ((void *)syllable, (void *)tmp, 1);
161       }
162  free ((void *)tmp);
163 }
164
165 /*
166 ** symb2name - convert symbol to it's name
167 ** INPUT:
168 **   char * - one symbol syllable
169 ** OUTPUT:
170 **   none.
171 ** NOTES:
172 **   none.
173 */
174 void
175 symb2name(char * syllable, char * h_syllable)
176 {
177  struct ssymb_names
178   {
179    char symbol;
180    char *name;
181   };
182  static struct ssymb_names ssn[42] =
183   {
184    {'1',"ONE"},
185    {'2',"TWO"},
186    {'3',"THREE"},
187    {'4',"FOUR"},
188    {'5',"FIVE"},
189    {'6',"SIX"},
190    {'7',"SEVEN"},
191    {'8',"EIGHT"},
192    {'9',"NINE"},
193    {'0',"ZERO"},
194    {33, "EXCLAMATION_POINT"},
195    {34, "QUOTATION_MARK"},
196    {35, "CROSSHATCH"},
197    {36, "DOLLAR_SIGN"},
198    {37, "PERCENT_SIGN"},
199    {38, "AMPERSAND"},
200    {39, "APOSTROPHE"},
201    {40, "LEFT_PARENTHESIS"},
202    {41, "RIGHT_PARENTHESIS"},
203    {42, "ASTERISK"},
204    {43, "PLUS_SIGN"},
205    {44, "COMMA"},
206    {45, "HYPHEN"},
207    {46, "PERIOD"},
208    {47, "SLASH"},
209    {58, "COLON"},
210    {59, "SEMICOLON"},
211    {60, "LESS_THAN"},
212    {61, "EQUAL_SIGN"},
213    {62, "GREATER_THAN"},
214    {63, "QUESTION_MARK"},
215    {64, "AT_SIGN"},
216    {91, "LEFT_BRACKET"},
217    {92, "BACKSLASH"},
218    {93, "RIGHT_BRACKET"},
219    {94, "CIRCUMFLEX"},
220    {95, "UNDERSCORE"},
221    {96, "GRAVE"},
222    {123, "LEFT_BRACE"},
223    {124, "VERTICAL_BAR"},
224    {125, "RIGHT_BRACE"},
225    {126, "TILDE"}
226   };
227  int i = 0;
228  int flag = FALSE;
229  
230  if (strlen(syllable) == 1)
231     {
232      for (i = 0; i < 42; i++)
233       {
234        if(*syllable == ssn[i].symbol)
235         {
236          (void)memcpy((void*)h_syllable, (void*)ssn[i].name, strlen(ssn[i].name));
237          flag = TRUE;
238         }
239       }
240      if (flag != TRUE)
241        (void)memcpy((void*)h_syllable, (void*)syllable, strlen(syllable));
242     }
243 }
244
245 /*
246 ** spell_word - spell the word
247 ** INPUT:
248 **   char * - pointer to the word
249 **   char * - pointer to the spelled word
250 ** OUTPUT:
251 **   char * - pointer to the spelled word
252 **    NULL  - something is wrong
253 ** NOTES:
254 **   You should free() memory pointed by spelled_word after each use of spell_word
255 */
256 char *
257 spell_word(char * word, char * spelled_word)
258 {
259  struct char_spell
260   {
261    char symbol;
262    char *name;
263   };
264  static struct char_spell cs[94] =
265   {
266    {'1',"ONE"              },
267    {'2',"TWO"              },
268    {'3',"THREE"            },
269    {'4',"FOUR"             },
270    {'5',"FIVE"             },
271    {'6',"SIX"              },
272    {'7',"SEVEN"            },
273    {'8',"EIGHT"            },
274    {'9',"NINE"             },
275    {'0',"ZERO"             },
276    {'A', "Alfa"            },
277    {'B', "Bravo"           },
278    {'C', "Charlie"         },
279    {'D', "Delta"           },
280    {'E', "Echo"            },
281    {'F', "Foxtrot"         },
282    {'G', "Golf"            },
283    {'H', "Hotel"           },
284    {'I', "India"           },
285    {'J', "Juliett"         },
286    {'K', "Kilo"            },
287    {'L', "Lima"            },
288    {'M', "Mike"            },
289    {'N', "November"        },
290    {'O', "Oscar"           },
291    {'P', "Papa"            },
292    {'Q', "Quebec"          },
293    {'R', "Romeo"           },
294    {'S', "Sierra"          },
295    {'T', "Tango"           },
296    {'U', "Uniform"         },
297    {'V', "Victor"          },
298    {'W', "Whiskey"         },
299    {'X', "X_ray"           },
300    {'Y', "Yankee"          },
301    {'Z', "Zulu"            },
302    {'a', "alfa"            },
303    {'b', "bravo"           },
304    {'c', "charlie"         },
305    {'d', "delta"           },
306    {'e', "echo"            },
307    {'f', "foxtrot"         },
308    {'g', "golf"            },
309    {'h', "hotel"           },
310    {'i', "india"           },
311    {'j', "juliett"         },
312    {'k', "kilo"            },
313    {'l', "lima"            },
314    {'m', "mike"            },
315    {'n', "november"        },
316    {'o', "oscar"           },
317    {'p', "papa"            },
318    {'q', "quebec"          },
319    {'r', "romeo"           },
320    {'s', "sierra"          },
321    {'t', "tango"           },
322    {'u', "uniform"         },
323    {'v', "victor"          },
324    {'w', "whiskey"         },
325    {'x', "x_ray"           },
326    {'y', "yankee"          },
327    {'z', "zulu"            },
328    {33, "EXCLAMATION_POINT"},
329    {34, "QUOTATION_MARK"   },
330    {35, "CROSSHATCH"       },
331    {36, "DOLLAR_SIGN"      },
332    {37, "PERCENT_SIGN"     },
333    {38, "AMPERSAND"        },
334    {39, "APOSTROPHE"       },
335    {40, "LEFT_PARENTHESIS" },
336    {41, "RIGHT_PARENTHESIS"},
337    {42, "ASTERISK"         },
338    {43, "PLUS_SIGN"        },
339    {44, "COMMA"            },
340    {45, "HYPHEN"           },
341    {46, "PERIOD"           },
342    {47, "SLASH"            },
343    {58, "COLON"            },
344    {59, "SEMICOLON"        },
345    {60, "LESS_THAN"        },
346    {61, "EQUAL_SIGN"       },
347    {62, "GREATER_THAN"     },
348    {63, "QUESTION_MARK"    },
349    {64, "AT_SIGN"          },
350    {91, "LEFT_BRACKET"     },
351    {92, "BACKSLASH"        },
352    {93, "RIGHT_BRACKET"    },
353    {94, "CIRCUMFLEX"       },
354    {95, "UNDERSCORE"       },
355    {96, "GRAVE"            },
356    {123, "LEFT_BRACE"      },
357    {124, "VERTICAL_BAR"    },
358    {125, "RIGHT_BRACE"     },
359    {126, "TILDE"           }
360   };
361   int s_length = 0;
362   int i = 0;
363   int j = 0;
364   int word_len = strlen(word);
365   char * tmp_ptr;
366   char hyphen = '-';
367   char zero   = 0x00;
368   
369   /* Count the length of the spelled word */
370   for (i=0; i <= word_len; i++)
371    for (j=0; j < 94; j++)
372     if (word[i] == cs[j].symbol)
373      {
374       s_length = s_length + strlen(cs[j].name) + 1;
375       continue;
376      }
377
378   /* Allocate memory for spelled word */
379   if ( (spelled_word = (char *)calloc(1, (size_t)s_length)) == NULL)
380     return(NULL);
381
382   /* Construct spelled word */
383   tmp_ptr = spelled_word;
384
385   for (i=0; i < word_len; i++)
386    for (j=0; j < 94; j++)
387     if (word[i] == cs[j].symbol)
388      {
389       (void) memcpy((void *)tmp_ptr, (void *)cs[j].name, strlen(cs[j].name));
390       tmp_ptr = tmp_ptr + strlen(cs[j].name);
391       /* Place the hyphen after each symbol */
392       (void) memcpy((void *)(tmp_ptr), (void *)&hyphen, 1);
393       tmp_ptr = tmp_ptr + 1;
394       continue;
395      }
396
397   /* Remove hyphen at the end of the word */
398   tmp_ptr = tmp_ptr - 1;
399   (void) memcpy((void *)(tmp_ptr), (void *)&zero, 1);
400
401   return (spelled_word);
402 }
403
404 #endif /* APGBFM */