2 ** This module uses code from the NIST implementation of FIPS-181,
3 ** but the algorythm is CHANGED and I think that I CAN
4 ** copyright it. See copiright notes below.
8 ** Copyright (c) 1999, 2000, 2001, 2002, 2003
9 ** Adel I. Mirzazhanov. All rights reserved
11 ** Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions
15 ** 1.Redistributions of source code must retain the above copyright notice,
16 ** this list of conditions and the following disclaimer.
17 ** 2.Redistributions in binary form must reproduce the above copyright
18 ** notice, this list of conditions and the following disclaimer in the
19 ** documentation and/or other materials provided with the distribution.
20 ** 3.The name of the author may not be used to endorse or promote products
21 ** derived from this software without specific prior written permission.
23 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
24 ** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
27 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 ** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 static struct unit rules[] =
54 {"b", NO_SPECIAL_RULE},
55 {"c", NO_SPECIAL_RULE},
56 {"d", NO_SPECIAL_RULE},
57 {"e", NO_FINAL_SPLIT | VOWEL},
58 {"f", NO_SPECIAL_RULE},
59 {"g", NO_SPECIAL_RULE},
60 {"h", NO_SPECIAL_RULE},
62 {"j", NO_SPECIAL_RULE},
63 {"k", NO_SPECIAL_RULE},
64 {"l", NO_SPECIAL_RULE},
65 {"m", NO_SPECIAL_RULE},
66 {"n", NO_SPECIAL_RULE},
68 {"p", NO_SPECIAL_RULE},
69 {"r", NO_SPECIAL_RULE},
70 {"s", NO_SPECIAL_RULE},
71 {"t", NO_SPECIAL_RULE},
73 {"v", NO_SPECIAL_RULE},
74 {"w", NO_SPECIAL_RULE},
75 {"x", NOT_BEGIN_SYLLABLE},
76 {"y", ALTERNATE_VOWEL | VOWEL},
77 {"z", NO_SPECIAL_RULE},
78 {"ch", NO_SPECIAL_RULE},
79 {"gh", NO_SPECIAL_RULE},
80 {"ph", NO_SPECIAL_RULE},
81 {"rh", NO_SPECIAL_RULE},
82 {"sh", NO_SPECIAL_RULE},
83 {"th", NO_SPECIAL_RULE},
84 {"wh", NO_SPECIAL_RULE},
85 {"qu", NO_SPECIAL_RULE},
86 {"ck", NOT_BEGIN_SYLLABLE}
89 static int digram[][RULE_SIZE] =
91 {/* aa */ ILLEGAL_PAIR,
92 /* ab */ ANY_COMBINATION,
93 /* ac */ ANY_COMBINATION,
94 /* ad */ ANY_COMBINATION,
95 /* ae */ ILLEGAL_PAIR,
96 /* af */ ANY_COMBINATION,
97 /* ag */ ANY_COMBINATION,
98 /* ah */ NOT_BEGIN | BREAK | NOT_END,
99 /* ai */ ANY_COMBINATION,
100 /* aj */ ANY_COMBINATION,
101 /* ak */ ANY_COMBINATION,
102 /* al */ ANY_COMBINATION,
103 /* am */ ANY_COMBINATION,
104 /* an */ ANY_COMBINATION,
105 /* ao */ ILLEGAL_PAIR,
106 /* ap */ ANY_COMBINATION,
107 /* ar */ ANY_COMBINATION,
108 /* as */ ANY_COMBINATION,
109 /* at */ ANY_COMBINATION,
110 /* au */ ANY_COMBINATION,
111 /* av */ ANY_COMBINATION,
112 /* aw */ ANY_COMBINATION,
113 /* ax */ ANY_COMBINATION,
114 /* ay */ ANY_COMBINATION,
115 /* az */ ANY_COMBINATION,
116 /* ach */ ANY_COMBINATION,
117 /* agh */ ILLEGAL_PAIR,
118 /* aph */ ANY_COMBINATION,
119 /* arh */ ILLEGAL_PAIR,
120 /* ash */ ANY_COMBINATION,
121 /* ath */ ANY_COMBINATION,
122 /* awh */ ILLEGAL_PAIR,
123 /* aqu */ BREAK | NOT_END,
124 /* ack */ ANY_COMBINATION},
125 {/* ba */ ANY_COMBINATION,
126 /* bb */ NOT_BEGIN | BREAK | NOT_END,
127 /* bc */ NOT_BEGIN | BREAK | NOT_END,
128 /* bd */ NOT_BEGIN | BREAK | NOT_END,
129 /* be */ ANY_COMBINATION,
130 /* bf */ NOT_BEGIN | BREAK | NOT_END,
131 /* bg */ NOT_BEGIN | BREAK | NOT_END,
132 /* bh */ NOT_BEGIN | BREAK | NOT_END,
133 /* bi */ ANY_COMBINATION,
134 /* bj */ NOT_BEGIN | BREAK | NOT_END,
135 /* bk */ NOT_BEGIN | BREAK | NOT_END,
136 /* bl */ BEGIN | SUFFIX | NOT_END,
137 /* bm */ NOT_BEGIN | BREAK | NOT_END,
138 /* bn */ NOT_BEGIN | BREAK | NOT_END,
139 /* bo */ ANY_COMBINATION,
140 /* bp */ NOT_BEGIN | BREAK | NOT_END,
141 /* br */ BEGIN | END,
143 /* bt */ NOT_BEGIN | BREAK | NOT_END,
144 /* bu */ ANY_COMBINATION,
145 /* bv */ NOT_BEGIN | BREAK | NOT_END,
146 /* bw */ NOT_BEGIN | BREAK | NOT_END,
147 /* bx */ ILLEGAL_PAIR,
148 /* by */ ANY_COMBINATION,
149 /* bz */ NOT_BEGIN | BREAK | NOT_END,
150 /* bch */ NOT_BEGIN | BREAK | NOT_END,
151 /* bgh */ ILLEGAL_PAIR,
152 /* bph */ NOT_BEGIN | BREAK | NOT_END,
153 /* brh */ ILLEGAL_PAIR,
154 /* bsh */ NOT_BEGIN | BREAK | NOT_END,
155 /* bth */ NOT_BEGIN | BREAK | NOT_END,
156 /* bwh */ ILLEGAL_PAIR,
157 /* bqu */ NOT_BEGIN | BREAK | NOT_END,
158 /* bck */ ILLEGAL_PAIR },
159 {/* ca */ ANY_COMBINATION,
160 /* cb */ NOT_BEGIN | BREAK | NOT_END,
161 /* cc */ NOT_BEGIN | BREAK | NOT_END,
162 /* cd */ NOT_BEGIN | BREAK | NOT_END,
163 /* ce */ ANY_COMBINATION,
164 /* cf */ NOT_BEGIN | BREAK | NOT_END,
165 /* cg */ NOT_BEGIN | BREAK | NOT_END,
166 /* ch */ NOT_BEGIN | BREAK | NOT_END,
167 /* ci */ ANY_COMBINATION,
168 /* cj */ NOT_BEGIN | BREAK | NOT_END,
169 /* ck */ NOT_BEGIN | BREAK | NOT_END,
170 /* cl */ SUFFIX | NOT_END,
171 /* cm */ NOT_BEGIN | BREAK | NOT_END,
172 /* cn */ NOT_BEGIN | BREAK | NOT_END,
173 /* co */ ANY_COMBINATION,
174 /* cp */ NOT_BEGIN | BREAK | NOT_END,
176 /* cs */ NOT_BEGIN | END,
177 /* ct */ NOT_BEGIN | PREFIX,
178 /* cu */ ANY_COMBINATION,
179 /* cv */ NOT_BEGIN | BREAK | NOT_END,
180 /* cw */ NOT_BEGIN | BREAK | NOT_END,
181 /* cx */ ILLEGAL_PAIR,
182 /* cy */ ANY_COMBINATION,
183 /* cz */ NOT_BEGIN | BREAK | NOT_END,
184 /* cch */ ILLEGAL_PAIR,
185 /* cgh */ ILLEGAL_PAIR,
186 /* cph */ NOT_BEGIN | BREAK | NOT_END,
187 /* crh */ ILLEGAL_PAIR,
188 /* csh */ NOT_BEGIN | BREAK | NOT_END,
189 /* cth */ NOT_BEGIN | BREAK | NOT_END,
190 /* cwh */ ILLEGAL_PAIR,
191 /* cqu */ NOT_BEGIN | SUFFIX | NOT_END,
192 /* cck */ ILLEGAL_PAIR},
193 {/* da */ ANY_COMBINATION,
194 /* db */ NOT_BEGIN | BREAK | NOT_END,
195 /* dc */ NOT_BEGIN | BREAK | NOT_END,
197 /* de */ ANY_COMBINATION,
198 /* df */ NOT_BEGIN | BREAK | NOT_END,
199 /* dg */ NOT_BEGIN | BREAK | NOT_END,
200 /* dh */ NOT_BEGIN | BREAK | NOT_END,
201 /* di */ ANY_COMBINATION,
202 /* dj */ NOT_BEGIN | BREAK | NOT_END,
203 /* dk */ NOT_BEGIN | BREAK | NOT_END,
204 /* dl */ NOT_BEGIN | BREAK | NOT_END,
205 /* dm */ NOT_BEGIN | BREAK | NOT_END,
206 /* dn */ NOT_BEGIN | BREAK | NOT_END,
207 /* do */ ANY_COMBINATION,
208 /* dp */ NOT_BEGIN | BREAK | NOT_END,
209 /* dr */ BEGIN | NOT_END,
210 /* ds */ NOT_BEGIN | END,
211 /* dt */ NOT_BEGIN | BREAK | NOT_END,
212 /* du */ ANY_COMBINATION,
213 /* dv */ NOT_BEGIN | BREAK | NOT_END,
214 /* dw */ NOT_BEGIN | BREAK | NOT_END,
215 /* dx */ ILLEGAL_PAIR,
216 /* dy */ ANY_COMBINATION,
217 /* dz */ NOT_BEGIN | BREAK | NOT_END,
218 /* dch */ NOT_BEGIN | BREAK | NOT_END,
219 /* dgh */ NOT_BEGIN | BREAK | NOT_END,
220 /* dph */ NOT_BEGIN | BREAK | NOT_END,
221 /* drh */ ILLEGAL_PAIR,
222 /* dsh */ NOT_BEGIN | NOT_END,
223 /* dth */ NOT_BEGIN | PREFIX,
224 /* dwh */ ILLEGAL_PAIR,
225 /* dqu */ NOT_BEGIN | BREAK | NOT_END,
226 /* dck */ ILLEGAL_PAIR },
227 {/* ea */ ANY_COMBINATION,
228 /* eb */ ANY_COMBINATION,
229 /* ec */ ANY_COMBINATION,
230 /* ed */ ANY_COMBINATION,
231 /* ee */ ANY_COMBINATION,
232 /* ef */ ANY_COMBINATION,
233 /* eg */ ANY_COMBINATION,
234 /* eh */ NOT_BEGIN | BREAK | NOT_END,
236 /* ej */ ANY_COMBINATION,
237 /* ek */ ANY_COMBINATION,
238 /* el */ ANY_COMBINATION,
239 /* em */ ANY_COMBINATION,
240 /* en */ ANY_COMBINATION,
242 /* ep */ ANY_COMBINATION,
243 /* er */ ANY_COMBINATION,
244 /* es */ ANY_COMBINATION,
245 /* et */ ANY_COMBINATION,
246 /* eu */ ANY_COMBINATION,
247 /* ev */ ANY_COMBINATION,
248 /* ew */ ANY_COMBINATION,
249 /* ex */ ANY_COMBINATION,
250 /* ey */ ANY_COMBINATION,
251 /* ez */ ANY_COMBINATION,
252 /* ech */ ANY_COMBINATION,
253 /* egh */ NOT_BEGIN | BREAK | NOT_END,
254 /* eph */ ANY_COMBINATION,
255 /* erh */ ILLEGAL_PAIR,
256 /* esh */ ANY_COMBINATION,
257 /* eth */ ANY_COMBINATION,
258 /* ewh */ ILLEGAL_PAIR,
259 /* equ */ BREAK | NOT_END,
260 /* eck */ ANY_COMBINATION },
261 {/* fa */ ANY_COMBINATION,
262 /* fb */ NOT_BEGIN | BREAK | NOT_END,
263 /* fc */ NOT_BEGIN | BREAK | NOT_END,
264 /* fd */ NOT_BEGIN | BREAK | NOT_END,
265 /* fe */ ANY_COMBINATION,
267 /* fg */ NOT_BEGIN | BREAK | NOT_END,
268 /* fh */ NOT_BEGIN | BREAK | NOT_END,
269 /* fi */ ANY_COMBINATION,
270 /* fj */ NOT_BEGIN | BREAK | NOT_END,
271 /* fk */ NOT_BEGIN | BREAK | NOT_END,
272 /* fl */ BEGIN | SUFFIX | NOT_END,
273 /* fm */ NOT_BEGIN | BREAK | NOT_END,
274 /* fn */ NOT_BEGIN | BREAK | NOT_END,
275 /* fo */ ANY_COMBINATION,
276 /* fp */ NOT_BEGIN | BREAK | NOT_END,
277 /* fr */ BEGIN | NOT_END,
280 /* fu */ ANY_COMBINATION,
281 /* fv */ NOT_BEGIN | BREAK | NOT_END,
282 /* fw */ NOT_BEGIN | BREAK | NOT_END,
283 /* fx */ ILLEGAL_PAIR,
285 /* fz */ NOT_BEGIN | BREAK | NOT_END,
286 /* fch */ NOT_BEGIN | BREAK | NOT_END,
287 /* fgh */ NOT_BEGIN | BREAK | NOT_END,
288 /* fph */ NOT_BEGIN | BREAK | NOT_END,
289 /* frh */ ILLEGAL_PAIR,
290 /* fsh */ NOT_BEGIN | BREAK | NOT_END,
291 /* fth */ NOT_BEGIN | BREAK | NOT_END,
292 /* fwh */ ILLEGAL_PAIR,
293 /* fqu */ NOT_BEGIN | BREAK | NOT_END,
294 /* fck */ ILLEGAL_PAIR },
295 {/* ga */ ANY_COMBINATION,
296 /* gb */ NOT_BEGIN | BREAK | NOT_END,
297 /* gc */ NOT_BEGIN | BREAK | NOT_END,
298 /* gd */ NOT_BEGIN | BREAK | NOT_END,
299 /* ge */ ANY_COMBINATION,
300 /* gf */ NOT_BEGIN | BREAK | NOT_END,
302 /* gh */ NOT_BEGIN | BREAK | NOT_END,
303 /* gi */ ANY_COMBINATION,
304 /* gj */ NOT_BEGIN | BREAK | NOT_END,
305 /* gk */ ILLEGAL_PAIR,
306 /* gl */ BEGIN | SUFFIX | NOT_END,
307 /* gm */ NOT_BEGIN | BREAK | NOT_END,
308 /* gn */ NOT_BEGIN | BREAK | NOT_END,
309 /* go */ ANY_COMBINATION,
310 /* gp */ NOT_BEGIN | BREAK | NOT_END,
311 /* gr */ BEGIN | NOT_END,
312 /* gs */ NOT_BEGIN | END,
313 /* gt */ NOT_BEGIN | BREAK | NOT_END,
314 /* gu */ ANY_COMBINATION,
315 /* gv */ NOT_BEGIN | BREAK | NOT_END,
316 /* gw */ NOT_BEGIN | BREAK | NOT_END,
317 /* gx */ ILLEGAL_PAIR,
319 /* gz */ NOT_BEGIN | BREAK | NOT_END,
320 /* gch */ NOT_BEGIN | BREAK | NOT_END,
321 /* ggh */ ILLEGAL_PAIR,
322 /* gph */ NOT_BEGIN | BREAK | NOT_END,
323 /* grh */ ILLEGAL_PAIR,
326 /* gwh */ ILLEGAL_PAIR,
327 /* gqu */ NOT_BEGIN | BREAK | NOT_END,
328 /* gck */ ILLEGAL_PAIR },
329 {/* ha */ ANY_COMBINATION,
330 /* hb */ NOT_BEGIN | BREAK | NOT_END,
331 /* hc */ NOT_BEGIN | BREAK | NOT_END,
332 /* hd */ NOT_BEGIN | BREAK | NOT_END,
333 /* he */ ANY_COMBINATION,
334 /* hf */ NOT_BEGIN | BREAK | NOT_END,
335 /* hg */ NOT_BEGIN | BREAK | NOT_END,
336 /* hh */ ILLEGAL_PAIR,
337 /* hi */ ANY_COMBINATION,
338 /* hj */ NOT_BEGIN | BREAK | NOT_END,
339 /* hk */ NOT_BEGIN | BREAK | NOT_END,
340 /* hl */ NOT_BEGIN | BREAK | NOT_END,
341 /* hm */ NOT_BEGIN | BREAK | NOT_END,
342 /* hn */ NOT_BEGIN | BREAK | NOT_END,
343 /* ho */ ANY_COMBINATION,
344 /* hp */ NOT_BEGIN | BREAK | NOT_END,
345 /* hr */ NOT_BEGIN | BREAK | NOT_END,
346 /* hs */ NOT_BEGIN | BREAK | NOT_END,
347 /* ht */ NOT_BEGIN | BREAK | NOT_END,
348 /* hu */ ANY_COMBINATION,
349 /* hv */ NOT_BEGIN | BREAK | NOT_END,
350 /* hw */ NOT_BEGIN | BREAK | NOT_END,
351 /* hx */ ILLEGAL_PAIR,
352 /* hy */ ANY_COMBINATION,
353 /* hz */ NOT_BEGIN | BREAK | NOT_END,
354 /* hch */ NOT_BEGIN | BREAK | NOT_END,
355 /* hgh */ NOT_BEGIN | BREAK | NOT_END,
356 /* hph */ NOT_BEGIN | BREAK | NOT_END,
357 /* hrh */ ILLEGAL_PAIR,
358 /* hsh */ NOT_BEGIN | BREAK | NOT_END,
359 /* hth */ NOT_BEGIN | BREAK | NOT_END,
360 /* hwh */ ILLEGAL_PAIR,
361 /* hqu */ NOT_BEGIN | BREAK | NOT_END,
362 /* hck */ ILLEGAL_PAIR },
363 {/* ia */ ANY_COMBINATION,
364 /* ib */ ANY_COMBINATION,
365 /* ic */ ANY_COMBINATION,
366 /* id */ ANY_COMBINATION,
368 /* if */ ANY_COMBINATION,
369 /* ig */ ANY_COMBINATION,
370 /* ih */ NOT_BEGIN | BREAK | NOT_END,
371 /* ii */ ILLEGAL_PAIR,
372 /* ij */ ANY_COMBINATION,
373 /* ik */ ANY_COMBINATION,
374 /* il */ ANY_COMBINATION,
375 /* im */ ANY_COMBINATION,
376 /* in */ ANY_COMBINATION,
378 /* ip */ ANY_COMBINATION,
379 /* ir */ ANY_COMBINATION,
380 /* is */ ANY_COMBINATION,
381 /* it */ ANY_COMBINATION,
382 /* iu */ NOT_BEGIN | BREAK | NOT_END,
383 /* iv */ ANY_COMBINATION,
384 /* iw */ NOT_BEGIN | BREAK | NOT_END,
385 /* ix */ ANY_COMBINATION,
386 /* iy */ NOT_BEGIN | BREAK | NOT_END,
387 /* iz */ ANY_COMBINATION,
388 /* ich */ ANY_COMBINATION,
390 /* iph */ ANY_COMBINATION,
391 /* irh */ ILLEGAL_PAIR,
392 /* ish */ ANY_COMBINATION,
393 /* ith */ ANY_COMBINATION,
394 /* iwh */ ILLEGAL_PAIR,
395 /* iqu */ BREAK | NOT_END,
396 /* ick */ ANY_COMBINATION },
397 {/* ja */ ANY_COMBINATION,
398 /* jb */ NOT_BEGIN | BREAK | NOT_END,
399 /* jc */ NOT_BEGIN | BREAK | NOT_END,
400 /* jd */ NOT_BEGIN | BREAK | NOT_END,
401 /* je */ ANY_COMBINATION,
402 /* jf */ NOT_BEGIN | BREAK | NOT_END,
403 /* jg */ ILLEGAL_PAIR,
404 /* jh */ NOT_BEGIN | BREAK | NOT_END,
405 /* ji */ ANY_COMBINATION,
406 /* jj */ ILLEGAL_PAIR,
407 /* jk */ NOT_BEGIN | BREAK | NOT_END,
408 /* jl */ NOT_BEGIN | BREAK | NOT_END,
409 /* jm */ NOT_BEGIN | BREAK | NOT_END,
410 /* jn */ NOT_BEGIN | BREAK | NOT_END,
411 /* jo */ ANY_COMBINATION,
412 /* jp */ NOT_BEGIN | BREAK | NOT_END,
413 /* jr */ NOT_BEGIN | BREAK | NOT_END,
414 /* js */ NOT_BEGIN | BREAK | NOT_END,
415 /* jt */ NOT_BEGIN | BREAK | NOT_END,
416 /* ju */ ANY_COMBINATION,
417 /* jv */ NOT_BEGIN | BREAK | NOT_END,
418 /* jw */ NOT_BEGIN | BREAK | NOT_END,
419 /* jx */ ILLEGAL_PAIR,
421 /* jz */ NOT_BEGIN | BREAK | NOT_END,
422 /* jch */ NOT_BEGIN | BREAK | NOT_END,
423 /* jgh */ NOT_BEGIN | BREAK | NOT_END,
424 /* jph */ NOT_BEGIN | BREAK | NOT_END,
425 /* jrh */ ILLEGAL_PAIR,
426 /* jsh */ NOT_BEGIN | BREAK | NOT_END,
427 /* jth */ NOT_BEGIN | BREAK | NOT_END,
428 /* jwh */ ILLEGAL_PAIR,
429 /* jqu */ NOT_BEGIN | BREAK | NOT_END,
430 /* jck */ ILLEGAL_PAIR },
431 {/* ka */ ANY_COMBINATION,
432 /* kb */ NOT_BEGIN | BREAK | NOT_END,
433 /* kc */ NOT_BEGIN | BREAK | NOT_END,
434 /* kd */ NOT_BEGIN | BREAK | NOT_END,
435 /* ke */ ANY_COMBINATION,
436 /* kf */ NOT_BEGIN | BREAK | NOT_END,
437 /* kg */ NOT_BEGIN | BREAK | NOT_END,
438 /* kh */ NOT_BEGIN | BREAK | NOT_END,
439 /* ki */ ANY_COMBINATION,
440 /* kj */ NOT_BEGIN | BREAK | NOT_END,
441 /* kk */ NOT_BEGIN | BREAK | NOT_END,
442 /* kl */ SUFFIX | NOT_END,
443 /* km */ NOT_BEGIN | BREAK | NOT_END,
444 /* kn */ BEGIN | SUFFIX | NOT_END,
445 /* ko */ ANY_COMBINATION,
446 /* kp */ NOT_BEGIN | BREAK | NOT_END,
447 /* kr */ SUFFIX | NOT_END,
448 /* ks */ NOT_BEGIN | END,
449 /* kt */ NOT_BEGIN | BREAK | NOT_END,
450 /* ku */ ANY_COMBINATION,
451 /* kv */ NOT_BEGIN | BREAK | NOT_END,
452 /* kw */ NOT_BEGIN | BREAK | NOT_END,
453 /* kx */ ILLEGAL_PAIR,
455 /* kz */ NOT_BEGIN | BREAK | NOT_END,
456 /* kch */ NOT_BEGIN | BREAK | NOT_END,
457 /* kgh */ NOT_BEGIN | BREAK | NOT_END,
458 /* kph */ NOT_BEGIN | PREFIX,
459 /* krh */ ILLEGAL_PAIR,
461 /* kth */ NOT_BEGIN | BREAK | NOT_END,
462 /* kwh */ ILLEGAL_PAIR,
463 /* kqu */ NOT_BEGIN | BREAK | NOT_END,
464 /* kck */ ILLEGAL_PAIR },
465 {/* la */ ANY_COMBINATION,
466 /* lb */ NOT_BEGIN | PREFIX,
467 /* lc */ NOT_BEGIN | BREAK | NOT_END,
468 /* ld */ NOT_BEGIN | PREFIX,
469 /* le */ ANY_COMBINATION,
470 /* lf */ NOT_BEGIN | PREFIX,
471 /* lg */ NOT_BEGIN | PREFIX,
472 /* lh */ NOT_BEGIN | BREAK | NOT_END,
473 /* li */ ANY_COMBINATION,
474 /* lj */ NOT_BEGIN | PREFIX,
475 /* lk */ NOT_BEGIN | PREFIX,
476 /* ll */ NOT_BEGIN | PREFIX,
477 /* lm */ NOT_BEGIN | PREFIX,
478 /* ln */ NOT_BEGIN | BREAK | NOT_END,
479 /* lo */ ANY_COMBINATION,
480 /* lp */ NOT_BEGIN | PREFIX,
481 /* lr */ NOT_BEGIN | BREAK | NOT_END,
483 /* lt */ NOT_BEGIN | PREFIX,
484 /* lu */ ANY_COMBINATION,
485 /* lv */ NOT_BEGIN | PREFIX,
486 /* lw */ NOT_BEGIN | BREAK | NOT_END,
487 /* lx */ ILLEGAL_PAIR,
488 /* ly */ ANY_COMBINATION,
489 /* lz */ NOT_BEGIN | BREAK | NOT_END,
490 /* lch */ NOT_BEGIN | PREFIX,
491 /* lgh */ NOT_BEGIN | BREAK | NOT_END,
492 /* lph */ NOT_BEGIN | PREFIX,
493 /* lrh */ ILLEGAL_PAIR,
494 /* lsh */ NOT_BEGIN | PREFIX,
495 /* lth */ NOT_BEGIN | PREFIX,
496 /* lwh */ ILLEGAL_PAIR,
497 /* lqu */ NOT_BEGIN | BREAK | NOT_END,
498 /* lck */ ILLEGAL_PAIR },
499 {/* ma */ ANY_COMBINATION,
500 /* mb */ NOT_BEGIN | BREAK | NOT_END,
501 /* mc */ NOT_BEGIN | BREAK | NOT_END,
502 /* md */ NOT_BEGIN | BREAK | NOT_END,
503 /* me */ ANY_COMBINATION,
504 /* mf */ NOT_BEGIN | BREAK | NOT_END,
505 /* mg */ NOT_BEGIN | BREAK | NOT_END,
506 /* mh */ NOT_BEGIN | BREAK | NOT_END,
507 /* mi */ ANY_COMBINATION,
508 /* mj */ NOT_BEGIN | BREAK | NOT_END,
509 /* mk */ NOT_BEGIN | BREAK | NOT_END,
510 /* ml */ NOT_BEGIN | BREAK | NOT_END,
512 /* mn */ NOT_BEGIN | BREAK | NOT_END,
513 /* mo */ ANY_COMBINATION,
515 /* mr */ NOT_BEGIN | BREAK | NOT_END,
518 /* mu */ ANY_COMBINATION,
519 /* mv */ NOT_BEGIN | BREAK | NOT_END,
520 /* mw */ NOT_BEGIN | BREAK | NOT_END,
521 /* mx */ ILLEGAL_PAIR,
522 /* my */ ANY_COMBINATION,
523 /* mz */ NOT_BEGIN | BREAK | NOT_END,
524 /* mch */ NOT_BEGIN | PREFIX,
525 /* mgh */ NOT_BEGIN | BREAK | NOT_END,
527 /* mrh */ ILLEGAL_PAIR,
530 /* mwh */ ILLEGAL_PAIR,
531 /* mqu */ NOT_BEGIN | BREAK | NOT_END,
532 /* mck */ ILLEGAL_PAIR },
533 {/* na */ ANY_COMBINATION,
534 /* nb */ NOT_BEGIN | BREAK | NOT_END,
535 /* nc */ NOT_BEGIN | BREAK | NOT_END,
537 /* ne */ ANY_COMBINATION,
538 /* nf */ NOT_BEGIN | BREAK | NOT_END,
539 /* ng */ NOT_BEGIN | PREFIX,
540 /* nh */ NOT_BEGIN | BREAK | NOT_END,
541 /* ni */ ANY_COMBINATION,
542 /* nj */ NOT_BEGIN | BREAK | NOT_END,
543 /* nk */ NOT_BEGIN | PREFIX,
544 /* nl */ NOT_BEGIN | BREAK | NOT_END,
545 /* nm */ NOT_BEGIN | BREAK | NOT_END,
547 /* no */ ANY_COMBINATION,
548 /* np */ NOT_BEGIN | BREAK | NOT_END,
549 /* nr */ NOT_BEGIN | BREAK | NOT_END,
552 /* nu */ ANY_COMBINATION,
553 /* nv */ NOT_BEGIN | BREAK | NOT_END,
554 /* nw */ NOT_BEGIN | BREAK | NOT_END,
555 /* nx */ ILLEGAL_PAIR,
557 /* nz */ NOT_BEGIN | BREAK | NOT_END,
558 /* nch */ NOT_BEGIN | PREFIX,
559 /* ngh */ NOT_BEGIN | BREAK | NOT_END,
560 /* nph */ NOT_BEGIN | PREFIX,
561 /* nrh */ ILLEGAL_PAIR,
564 /* nwh */ ILLEGAL_PAIR,
565 /* nqu */ NOT_BEGIN | BREAK | NOT_END,
566 /* nck */ NOT_BEGIN | PREFIX },
567 {/* oa */ ANY_COMBINATION,
568 /* ob */ ANY_COMBINATION,
569 /* oc */ ANY_COMBINATION,
570 /* od */ ANY_COMBINATION,
571 /* oe */ ILLEGAL_PAIR,
572 /* of */ ANY_COMBINATION,
573 /* og */ ANY_COMBINATION,
574 /* oh */ NOT_BEGIN | BREAK | NOT_END,
575 /* oi */ ANY_COMBINATION,
576 /* oj */ ANY_COMBINATION,
577 /* ok */ ANY_COMBINATION,
578 /* ol */ ANY_COMBINATION,
579 /* om */ ANY_COMBINATION,
580 /* on */ ANY_COMBINATION,
581 /* oo */ ANY_COMBINATION,
582 /* op */ ANY_COMBINATION,
583 /* or */ ANY_COMBINATION,
584 /* os */ ANY_COMBINATION,
585 /* ot */ ANY_COMBINATION,
586 /* ou */ ANY_COMBINATION,
587 /* ov */ ANY_COMBINATION,
588 /* ow */ ANY_COMBINATION,
589 /* ox */ ANY_COMBINATION,
590 /* oy */ ANY_COMBINATION,
591 /* oz */ ANY_COMBINATION,
592 /* och */ ANY_COMBINATION,
594 /* oph */ ANY_COMBINATION,
595 /* orh */ ILLEGAL_PAIR,
596 /* osh */ ANY_COMBINATION,
597 /* oth */ ANY_COMBINATION,
598 /* owh */ ILLEGAL_PAIR,
599 /* oqu */ BREAK | NOT_END,
600 /* ock */ ANY_COMBINATION },
601 {/* pa */ ANY_COMBINATION,
602 /* pb */ NOT_BEGIN | BREAK | NOT_END,
603 /* pc */ NOT_BEGIN | BREAK | NOT_END,
604 /* pd */ NOT_BEGIN | BREAK | NOT_END,
605 /* pe */ ANY_COMBINATION,
606 /* pf */ NOT_BEGIN | BREAK | NOT_END,
607 /* pg */ NOT_BEGIN | BREAK | NOT_END,
608 /* ph */ NOT_BEGIN | BREAK | NOT_END,
609 /* pi */ ANY_COMBINATION,
610 /* pj */ NOT_BEGIN | BREAK | NOT_END,
611 /* pk */ NOT_BEGIN | BREAK | NOT_END,
612 /* pl */ SUFFIX | NOT_END,
613 /* pm */ NOT_BEGIN | BREAK | NOT_END,
614 /* pn */ NOT_BEGIN | BREAK | NOT_END,
615 /* po */ ANY_COMBINATION,
616 /* pp */ NOT_BEGIN | PREFIX,
618 /* ps */ NOT_BEGIN | END,
619 /* pt */ NOT_BEGIN | END,
620 /* pu */ NOT_BEGIN | END,
621 /* pv */ NOT_BEGIN | BREAK | NOT_END,
622 /* pw */ NOT_BEGIN | BREAK | NOT_END,
623 /* px */ ILLEGAL_PAIR,
624 /* py */ ANY_COMBINATION,
625 /* pz */ NOT_BEGIN | BREAK | NOT_END,
626 /* pch */ NOT_BEGIN | BREAK | NOT_END,
627 /* pgh */ NOT_BEGIN | BREAK | NOT_END,
628 /* pph */ NOT_BEGIN | BREAK | NOT_END,
629 /* prh */ ILLEGAL_PAIR,
630 /* psh */ NOT_BEGIN | BREAK | NOT_END,
631 /* pth */ NOT_BEGIN | BREAK | NOT_END,
632 /* pwh */ ILLEGAL_PAIR,
633 /* pqu */ NOT_BEGIN | BREAK | NOT_END,
634 /* pck */ ILLEGAL_PAIR },
635 {/* ra */ ANY_COMBINATION,
636 /* rb */ NOT_BEGIN | PREFIX,
637 /* rc */ NOT_BEGIN | PREFIX,
638 /* rd */ NOT_BEGIN | PREFIX,
639 /* re */ ANY_COMBINATION,
640 /* rf */ NOT_BEGIN | PREFIX,
641 /* rg */ NOT_BEGIN | PREFIX,
642 /* rh */ NOT_BEGIN | BREAK | NOT_END,
643 /* ri */ ANY_COMBINATION,
644 /* rj */ NOT_BEGIN | PREFIX,
645 /* rk */ NOT_BEGIN | PREFIX,
646 /* rl */ NOT_BEGIN | PREFIX,
647 /* rm */ NOT_BEGIN | PREFIX,
648 /* rn */ NOT_BEGIN | PREFIX,
649 /* ro */ ANY_COMBINATION,
650 /* rp */ NOT_BEGIN | PREFIX,
651 /* rr */ NOT_BEGIN | PREFIX,
652 /* rs */ NOT_BEGIN | PREFIX,
653 /* rt */ NOT_BEGIN | PREFIX,
654 /* ru */ ANY_COMBINATION,
655 /* rv */ NOT_BEGIN | PREFIX,
656 /* rw */ NOT_BEGIN | BREAK | NOT_END,
657 /* rx */ ILLEGAL_PAIR,
658 /* ry */ ANY_COMBINATION,
659 /* rz */ NOT_BEGIN | PREFIX,
660 /* rch */ NOT_BEGIN | PREFIX,
661 /* rgh */ NOT_BEGIN | BREAK | NOT_END,
662 /* rph */ NOT_BEGIN | PREFIX,
663 /* rrh */ ILLEGAL_PAIR,
664 /* rsh */ NOT_BEGIN | PREFIX,
665 /* rth */ NOT_BEGIN | PREFIX,
666 /* rwh */ ILLEGAL_PAIR,
667 /* rqu */ NOT_BEGIN | PREFIX | NOT_END,
668 /* rck */ NOT_BEGIN | PREFIX },
669 {/* sa */ ANY_COMBINATION,
670 /* sb */ NOT_BEGIN | BREAK | NOT_END,
672 /* sd */ NOT_BEGIN | BREAK | NOT_END,
673 /* se */ ANY_COMBINATION,
674 /* sf */ NOT_BEGIN | BREAK | NOT_END,
675 /* sg */ NOT_BEGIN | BREAK | NOT_END,
676 /* sh */ NOT_BEGIN | BREAK | NOT_END,
677 /* si */ ANY_COMBINATION,
678 /* sj */ NOT_BEGIN | BREAK | NOT_END,
679 /* sk */ ANY_COMBINATION,
680 /* sl */ BEGIN | SUFFIX | NOT_END,
681 /* sm */ SUFFIX | NOT_END,
682 /* sn */ PREFIX | SUFFIX | NOT_END,
683 /* so */ ANY_COMBINATION,
684 /* sp */ ANY_COMBINATION,
685 /* sr */ NOT_BEGIN | NOT_END,
686 /* ss */ NOT_BEGIN | PREFIX,
687 /* st */ ANY_COMBINATION,
688 /* su */ ANY_COMBINATION,
689 /* sv */ NOT_BEGIN | BREAK | NOT_END,
690 /* sw */ BEGIN | SUFFIX | NOT_END,
691 /* sx */ ILLEGAL_PAIR,
692 /* sy */ ANY_COMBINATION,
693 /* sz */ NOT_BEGIN | BREAK | NOT_END,
694 /* sch */ BEGIN | SUFFIX | NOT_END,
695 /* sgh */ NOT_BEGIN | BREAK | NOT_END,
696 /* sph */ NOT_BEGIN | BREAK | NOT_END,
697 /* srh */ ILLEGAL_PAIR,
698 /* ssh */ NOT_BEGIN | BREAK | NOT_END,
699 /* sth */ NOT_BEGIN | BREAK | NOT_END,
700 /* swh */ ILLEGAL_PAIR,
701 /* squ */ SUFFIX | NOT_END,
702 /* sck */ NOT_BEGIN },
703 {/* ta */ ANY_COMBINATION,
704 /* tb */ NOT_BEGIN | BREAK | NOT_END,
705 /* tc */ NOT_BEGIN | BREAK | NOT_END,
706 /* td */ NOT_BEGIN | BREAK | NOT_END,
707 /* te */ ANY_COMBINATION,
708 /* tf */ NOT_BEGIN | BREAK | NOT_END,
709 /* tg */ NOT_BEGIN | BREAK | NOT_END,
710 /* th */ NOT_BEGIN | BREAK | NOT_END,
711 /* ti */ ANY_COMBINATION,
712 /* tj */ NOT_BEGIN | BREAK | NOT_END,
713 /* tk */ NOT_BEGIN | BREAK | NOT_END,
714 /* tl */ NOT_BEGIN | BREAK | NOT_END,
715 /* tm */ NOT_BEGIN | BREAK | NOT_END,
716 /* tn */ NOT_BEGIN | BREAK | NOT_END,
717 /* to */ ANY_COMBINATION,
718 /* tp */ NOT_BEGIN | BREAK | NOT_END,
720 /* ts */ NOT_BEGIN | END,
721 /* tt */ NOT_BEGIN | PREFIX,
722 /* tu */ ANY_COMBINATION,
723 /* tv */ NOT_BEGIN | BREAK | NOT_END,
724 /* tw */ BEGIN | SUFFIX | NOT_END,
725 /* tx */ ILLEGAL_PAIR,
726 /* ty */ ANY_COMBINATION,
727 /* tz */ NOT_BEGIN | BREAK | NOT_END,
729 /* tgh */ NOT_BEGIN | BREAK | NOT_END,
730 /* tph */ NOT_BEGIN | END,
731 /* trh */ ILLEGAL_PAIR,
732 /* tsh */ NOT_BEGIN | END,
733 /* tth */ NOT_BEGIN | BREAK | NOT_END,
734 /* twh */ ILLEGAL_PAIR,
735 /* tqu */ NOT_BEGIN | BREAK | NOT_END,
736 /* tck */ ILLEGAL_PAIR },
737 {/* ua */ NOT_BEGIN | BREAK | NOT_END,
738 /* ub */ ANY_COMBINATION,
739 /* uc */ ANY_COMBINATION,
740 /* ud */ ANY_COMBINATION,
742 /* uf */ ANY_COMBINATION,
743 /* ug */ ANY_COMBINATION,
744 /* uh */ NOT_BEGIN | BREAK | NOT_END,
745 /* ui */ NOT_BEGIN | BREAK | NOT_END,
746 /* uj */ ANY_COMBINATION,
747 /* uk */ ANY_COMBINATION,
748 /* ul */ ANY_COMBINATION,
749 /* um */ ANY_COMBINATION,
750 /* un */ ANY_COMBINATION,
751 /* uo */ NOT_BEGIN | BREAK,
752 /* up */ ANY_COMBINATION,
753 /* ur */ ANY_COMBINATION,
754 /* us */ ANY_COMBINATION,
755 /* ut */ ANY_COMBINATION,
756 /* uu */ ILLEGAL_PAIR,
757 /* uv */ ANY_COMBINATION,
758 /* uw */ NOT_BEGIN | BREAK | NOT_END,
759 /* ux */ ANY_COMBINATION,
760 /* uy */ NOT_BEGIN | BREAK | NOT_END,
761 /* uz */ ANY_COMBINATION,
762 /* uch */ ANY_COMBINATION,
763 /* ugh */ NOT_BEGIN | PREFIX,
764 /* uph */ ANY_COMBINATION,
765 /* urh */ ILLEGAL_PAIR,
766 /* ush */ ANY_COMBINATION,
767 /* uth */ ANY_COMBINATION,
768 /* uwh */ ILLEGAL_PAIR,
769 /* uqu */ BREAK | NOT_END,
770 /* uck */ ANY_COMBINATION },
771 {/* va */ ANY_COMBINATION,
772 /* vb */ NOT_BEGIN | BREAK | NOT_END,
773 /* vc */ NOT_BEGIN | BREAK | NOT_END,
774 /* vd */ NOT_BEGIN | BREAK | NOT_END,
775 /* ve */ ANY_COMBINATION,
776 /* vf */ NOT_BEGIN | BREAK | NOT_END,
777 /* vg */ NOT_BEGIN | BREAK | NOT_END,
778 /* vh */ NOT_BEGIN | BREAK | NOT_END,
779 /* vi */ ANY_COMBINATION,
780 /* vj */ NOT_BEGIN | BREAK | NOT_END,
781 /* vk */ NOT_BEGIN | BREAK | NOT_END,
782 /* vl */ NOT_BEGIN | BREAK | NOT_END,
783 /* vm */ NOT_BEGIN | BREAK | NOT_END,
784 /* vn */ NOT_BEGIN | BREAK | NOT_END,
785 /* vo */ ANY_COMBINATION,
786 /* vp */ NOT_BEGIN | BREAK | NOT_END,
787 /* vr */ NOT_BEGIN | BREAK | NOT_END,
788 /* vs */ NOT_BEGIN | BREAK | NOT_END,
789 /* vt */ NOT_BEGIN | BREAK | NOT_END,
790 /* vu */ ANY_COMBINATION,
791 /* vv */ NOT_BEGIN | BREAK | NOT_END,
792 /* vw */ NOT_BEGIN | BREAK | NOT_END,
793 /* vx */ ILLEGAL_PAIR,
795 /* vz */ NOT_BEGIN | BREAK | NOT_END,
796 /* vch */ NOT_BEGIN | BREAK | NOT_END,
797 /* vgh */ NOT_BEGIN | BREAK | NOT_END,
798 /* vph */ NOT_BEGIN | BREAK | NOT_END,
799 /* vrh */ ILLEGAL_PAIR,
800 /* vsh */ NOT_BEGIN | BREAK | NOT_END,
801 /* vth */ NOT_BEGIN | BREAK | NOT_END,
802 /* vwh */ ILLEGAL_PAIR,
803 /* vqu */ NOT_BEGIN | BREAK | NOT_END,
804 /* vck */ ILLEGAL_PAIR },
805 {/* wa */ ANY_COMBINATION,
806 /* wb */ NOT_BEGIN | PREFIX,
807 /* wc */ NOT_BEGIN | BREAK | NOT_END,
808 /* wd */ NOT_BEGIN | PREFIX | END,
809 /* we */ ANY_COMBINATION,
810 /* wf */ NOT_BEGIN | PREFIX,
811 /* wg */ NOT_BEGIN | PREFIX | END,
812 /* wh */ NOT_BEGIN | BREAK | NOT_END,
813 /* wi */ ANY_COMBINATION,
814 /* wj */ NOT_BEGIN | BREAK | NOT_END,
815 /* wk */ NOT_BEGIN | PREFIX,
816 /* wl */ NOT_BEGIN | PREFIX | SUFFIX,
817 /* wm */ NOT_BEGIN | PREFIX,
818 /* wn */ NOT_BEGIN | PREFIX,
819 /* wo */ ANY_COMBINATION,
820 /* wp */ NOT_BEGIN | PREFIX,
821 /* wr */ BEGIN | SUFFIX | NOT_END,
822 /* ws */ NOT_BEGIN | PREFIX,
823 /* wt */ NOT_BEGIN | PREFIX,
824 /* wu */ ANY_COMBINATION,
825 /* wv */ NOT_BEGIN | PREFIX,
826 /* ww */ NOT_BEGIN | BREAK | NOT_END,
827 /* wx */ NOT_BEGIN | PREFIX,
828 /* wy */ ANY_COMBINATION,
829 /* wz */ NOT_BEGIN | PREFIX,
831 /* wgh */ NOT_BEGIN | BREAK | NOT_END,
833 /* wrh */ ILLEGAL_PAIR,
836 /* wwh */ ILLEGAL_PAIR,
837 /* wqu */ NOT_BEGIN | BREAK | NOT_END,
838 /* wck */ NOT_BEGIN },
840 /* xb */ NOT_BEGIN | BREAK | NOT_END,
841 /* xc */ NOT_BEGIN | BREAK | NOT_END,
842 /* xd */ NOT_BEGIN | BREAK | NOT_END,
844 /* xf */ NOT_BEGIN | BREAK | NOT_END,
845 /* xg */ NOT_BEGIN | BREAK | NOT_END,
846 /* xh */ NOT_BEGIN | BREAK | NOT_END,
848 /* xj */ NOT_BEGIN | BREAK | NOT_END,
849 /* xk */ NOT_BEGIN | BREAK | NOT_END,
850 /* xl */ NOT_BEGIN | BREAK | NOT_END,
851 /* xm */ NOT_BEGIN | BREAK | NOT_END,
852 /* xn */ NOT_BEGIN | BREAK | NOT_END,
854 /* xp */ NOT_BEGIN | BREAK | NOT_END,
855 /* xr */ NOT_BEGIN | BREAK | NOT_END,
856 /* xs */ NOT_BEGIN | BREAK | NOT_END,
857 /* xt */ NOT_BEGIN | BREAK | NOT_END,
859 /* xv */ NOT_BEGIN | BREAK | NOT_END,
860 /* xw */ NOT_BEGIN | BREAK | NOT_END,
861 /* xx */ ILLEGAL_PAIR,
863 /* xz */ NOT_BEGIN | BREAK | NOT_END,
864 /* xch */ NOT_BEGIN | BREAK | NOT_END,
865 /* xgh */ NOT_BEGIN | BREAK | NOT_END,
866 /* xph */ NOT_BEGIN | BREAK | NOT_END,
867 /* xrh */ ILLEGAL_PAIR,
868 /* xsh */ NOT_BEGIN | BREAK | NOT_END,
869 /* xth */ NOT_BEGIN | BREAK | NOT_END,
870 /* xwh */ ILLEGAL_PAIR,
871 /* xqu */ NOT_BEGIN | BREAK | NOT_END,
872 /* xck */ ILLEGAL_PAIR },
873 {/* ya */ ANY_COMBINATION,
875 /* yc */ NOT_BEGIN | NOT_END,
877 /* ye */ ANY_COMBINATION,
878 /* yf */ NOT_BEGIN | NOT_END,
880 /* yh */ NOT_BEGIN | BREAK | NOT_END,
881 /* yi */ BEGIN | NOT_END,
882 /* yj */ NOT_BEGIN | NOT_END,
884 /* yl */ NOT_BEGIN | NOT_END,
887 /* yo */ ANY_COMBINATION,
889 /* yr */ NOT_BEGIN | BREAK | NOT_END,
892 /* yu */ ANY_COMBINATION,
893 /* yv */ NOT_BEGIN | NOT_END,
894 /* yw */ NOT_BEGIN | BREAK | NOT_END,
896 /* yy */ ILLEGAL_PAIR,
898 /* ych */ NOT_BEGIN | BREAK | NOT_END,
899 /* ygh */ NOT_BEGIN | BREAK | NOT_END,
900 /* yph */ NOT_BEGIN | BREAK | NOT_END,
901 /* yrh */ ILLEGAL_PAIR,
902 /* ysh */ NOT_BEGIN | BREAK | NOT_END,
903 /* yth */ NOT_BEGIN | BREAK | NOT_END,
904 /* ywh */ ILLEGAL_PAIR,
905 /* yqu */ NOT_BEGIN | BREAK | NOT_END,
906 /* yck */ ILLEGAL_PAIR },
907 {/* za */ ANY_COMBINATION,
908 /* zb */ NOT_BEGIN | BREAK | NOT_END,
909 /* zc */ NOT_BEGIN | BREAK | NOT_END,
910 /* zd */ NOT_BEGIN | BREAK | NOT_END,
911 /* ze */ ANY_COMBINATION,
912 /* zf */ NOT_BEGIN | BREAK | NOT_END,
913 /* zg */ NOT_BEGIN | BREAK | NOT_END,
914 /* zh */ NOT_BEGIN | BREAK | NOT_END,
915 /* zi */ ANY_COMBINATION,
916 /* zj */ NOT_BEGIN | BREAK | NOT_END,
917 /* zk */ NOT_BEGIN | BREAK | NOT_END,
918 /* zl */ NOT_BEGIN | BREAK | NOT_END,
919 /* zm */ NOT_BEGIN | BREAK | NOT_END,
920 /* zn */ NOT_BEGIN | BREAK | NOT_END,
921 /* zo */ ANY_COMBINATION,
922 /* zp */ NOT_BEGIN | BREAK | NOT_END,
923 /* zr */ NOT_BEGIN | NOT_END,
924 /* zs */ NOT_BEGIN | BREAK | NOT_END,
926 /* zu */ ANY_COMBINATION,
927 /* zv */ NOT_BEGIN | BREAK | NOT_END,
928 /* zw */ SUFFIX | NOT_END,
929 /* zx */ ILLEGAL_PAIR,
930 /* zy */ ANY_COMBINATION,
932 /* zch */ NOT_BEGIN | BREAK | NOT_END,
933 /* zgh */ NOT_BEGIN | BREAK | NOT_END,
934 /* zph */ NOT_BEGIN | BREAK | NOT_END,
935 /* zrh */ ILLEGAL_PAIR,
936 /* zsh */ NOT_BEGIN | BREAK | NOT_END,
937 /* zth */ NOT_BEGIN | BREAK | NOT_END,
938 /* zwh */ ILLEGAL_PAIR,
939 /* zqu */ NOT_BEGIN | BREAK | NOT_END,
940 /* zck */ ILLEGAL_PAIR },
941 {/* cha */ ANY_COMBINATION,
942 /* chb */ NOT_BEGIN | BREAK | NOT_END,
943 /* chc */ NOT_BEGIN | BREAK | NOT_END,
944 /* chd */ NOT_BEGIN | BREAK | NOT_END,
945 /* che */ ANY_COMBINATION,
946 /* chf */ NOT_BEGIN | BREAK | NOT_END,
947 /* chg */ NOT_BEGIN | BREAK | NOT_END,
948 /* chh */ NOT_BEGIN | BREAK | NOT_END,
949 /* chi */ ANY_COMBINATION,
950 /* chj */ NOT_BEGIN | BREAK | NOT_END,
951 /* chk */ NOT_BEGIN | BREAK | NOT_END,
952 /* chl */ NOT_BEGIN | BREAK | NOT_END,
953 /* chm */ NOT_BEGIN | BREAK | NOT_END,
954 /* chn */ NOT_BEGIN | BREAK | NOT_END,
955 /* cho */ ANY_COMBINATION,
956 /* chp */ NOT_BEGIN | BREAK | NOT_END,
958 /* chs */ NOT_BEGIN | BREAK | NOT_END,
959 /* cht */ NOT_BEGIN | BREAK | NOT_END,
960 /* chu */ ANY_COMBINATION,
961 /* chv */ NOT_BEGIN | BREAK | NOT_END,
962 /* chw */ NOT_BEGIN | NOT_END,
963 /* chx */ ILLEGAL_PAIR,
964 /* chy */ ANY_COMBINATION,
965 /* chz */ NOT_BEGIN | BREAK | NOT_END,
966 /* chch */ ILLEGAL_PAIR,
967 /* chgh */ NOT_BEGIN | BREAK | NOT_END,
968 /* chph */ NOT_BEGIN | BREAK | NOT_END,
969 /* chrh */ ILLEGAL_PAIR,
970 /* chsh */ NOT_BEGIN | BREAK | NOT_END,
971 /* chth */ NOT_BEGIN | BREAK | NOT_END,
972 /* chwh */ ILLEGAL_PAIR,
973 /* chqu */ NOT_BEGIN | BREAK | NOT_END,
974 /* chck */ ILLEGAL_PAIR },
975 {/* gha */ ANY_COMBINATION,
976 /* ghb */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
977 /* ghc */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
978 /* ghd */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
979 /* ghe */ ANY_COMBINATION,
980 /* ghf */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
981 /* ghg */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
982 /* ghh */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
983 /* ghi */ BEGIN | NOT_END,
984 /* ghj */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
985 /* ghk */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
986 /* ghl */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
987 /* ghm */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
988 /* ghn */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
989 /* gho */ BEGIN | NOT_END,
990 /* ghp */ NOT_BEGIN | BREAK | NOT_END,
991 /* ghr */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
992 /* ghs */ NOT_BEGIN | PREFIX,
993 /* ght */ NOT_BEGIN | PREFIX,
994 /* ghu */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
995 /* ghv */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
996 /* ghw */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
997 /* ghx */ ILLEGAL_PAIR,
998 /* ghy */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
999 /* ghz */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
1000 /* ghch */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
1001 /* ghgh */ ILLEGAL_PAIR,
1002 /* ghph */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
1003 /* ghrh */ ILLEGAL_PAIR,
1004 /* ghsh */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
1005 /* ghth */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
1006 /* ghwh */ ILLEGAL_PAIR,
1007 /* ghqu */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
1008 /* ghck */ ILLEGAL_PAIR },
1009 {/* pha */ ANY_COMBINATION,
1010 /* phb */ NOT_BEGIN | BREAK | NOT_END,
1011 /* phc */ NOT_BEGIN | BREAK | NOT_END,
1012 /* phd */ NOT_BEGIN | BREAK | NOT_END,
1013 /* phe */ ANY_COMBINATION,
1014 /* phf */ NOT_BEGIN | BREAK | NOT_END,
1015 /* phg */ NOT_BEGIN | BREAK | NOT_END,
1016 /* phh */ NOT_BEGIN | BREAK | NOT_END,
1017 /* phi */ ANY_COMBINATION,
1018 /* phj */ NOT_BEGIN | BREAK | NOT_END,
1019 /* phk */ NOT_BEGIN | BREAK | NOT_END,
1020 /* phl */ BEGIN | SUFFIX | NOT_END,
1021 /* phm */ NOT_BEGIN | BREAK | NOT_END,
1022 /* phn */ NOT_BEGIN | BREAK | NOT_END,
1023 /* pho */ ANY_COMBINATION,
1024 /* php */ NOT_BEGIN | BREAK | NOT_END,
1026 /* phs */ NOT_BEGIN,
1027 /* pht */ NOT_BEGIN,
1028 /* phu */ ANY_COMBINATION,
1029 /* phv */ NOT_BEGIN | NOT_END,
1030 /* phw */ NOT_BEGIN | NOT_END,
1031 /* phx */ ILLEGAL_PAIR,
1032 /* phy */ NOT_BEGIN,
1033 /* phz */ NOT_BEGIN | BREAK | NOT_END,
1034 /* phch */ NOT_BEGIN | BREAK | NOT_END,
1035 /* phgh */ NOT_BEGIN | BREAK | NOT_END,
1036 /* phph */ ILLEGAL_PAIR,
1037 /* phrh */ ILLEGAL_PAIR,
1038 /* phsh */ NOT_BEGIN | BREAK | NOT_END,
1039 /* phth */ NOT_BEGIN | BREAK | NOT_END,
1040 /* phwh */ ILLEGAL_PAIR,
1041 /* phqu */ NOT_BEGIN | BREAK | NOT_END,
1042 /* phck */ ILLEGAL_PAIR },
1043 {/* rha */ BEGIN | NOT_END,
1044 /* rhb */ ILLEGAL_PAIR,
1045 /* rhc */ ILLEGAL_PAIR,
1046 /* rhd */ ILLEGAL_PAIR,
1047 /* rhe */ BEGIN | NOT_END,
1048 /* rhf */ ILLEGAL_PAIR,
1049 /* rhg */ ILLEGAL_PAIR,
1050 /* rhh */ ILLEGAL_PAIR,
1051 /* rhi */ BEGIN | NOT_END,
1052 /* rhj */ ILLEGAL_PAIR,
1053 /* rhk */ ILLEGAL_PAIR,
1054 /* rhl */ ILLEGAL_PAIR,
1055 /* rhm */ ILLEGAL_PAIR,
1056 /* rhn */ ILLEGAL_PAIR,
1057 /* rho */ BEGIN | NOT_END,
1058 /* rhp */ ILLEGAL_PAIR,
1059 /* rhr */ ILLEGAL_PAIR,
1060 /* rhs */ ILLEGAL_PAIR,
1061 /* rht */ ILLEGAL_PAIR,
1062 /* rhu */ BEGIN | NOT_END,
1063 /* rhv */ ILLEGAL_PAIR,
1064 /* rhw */ ILLEGAL_PAIR,
1065 /* rhx */ ILLEGAL_PAIR,
1066 /* rhy */ BEGIN | NOT_END,
1067 /* rhz */ ILLEGAL_PAIR,
1068 /* rhch */ ILLEGAL_PAIR,
1069 /* rhgh */ ILLEGAL_PAIR,
1070 /* rhph */ ILLEGAL_PAIR,
1071 /* rhrh */ ILLEGAL_PAIR,
1072 /* rhsh */ ILLEGAL_PAIR,
1073 /* rhth */ ILLEGAL_PAIR,
1074 /* rhwh */ ILLEGAL_PAIR,
1075 /* rhqu */ ILLEGAL_PAIR,
1076 /* rhck */ ILLEGAL_PAIR },
1077 {/* sha */ ANY_COMBINATION,
1078 /* shb */ NOT_BEGIN | BREAK | NOT_END,
1079 /* shc */ NOT_BEGIN | BREAK | NOT_END,
1080 /* shd */ NOT_BEGIN | BREAK | NOT_END,
1081 /* she */ ANY_COMBINATION,
1082 /* shf */ NOT_BEGIN | BREAK | NOT_END,
1083 /* shg */ NOT_BEGIN | BREAK | NOT_END,
1084 /* shh */ ILLEGAL_PAIR,
1085 /* shi */ ANY_COMBINATION,
1086 /* shj */ NOT_BEGIN | BREAK | NOT_END,
1087 /* shk */ NOT_BEGIN,
1088 /* shl */ BEGIN | SUFFIX | NOT_END,
1089 /* shm */ BEGIN | SUFFIX | NOT_END,
1090 /* shn */ BEGIN | SUFFIX | NOT_END,
1091 /* sho */ ANY_COMBINATION,
1092 /* shp */ NOT_BEGIN,
1093 /* shr */ BEGIN | SUFFIX | NOT_END,
1094 /* shs */ NOT_BEGIN | BREAK | NOT_END,
1096 /* shu */ ANY_COMBINATION,
1097 /* shv */ NOT_BEGIN | BREAK | NOT_END,
1098 /* shw */ SUFFIX | NOT_END,
1099 /* shx */ ILLEGAL_PAIR,
1100 /* shy */ ANY_COMBINATION,
1101 /* shz */ NOT_BEGIN | BREAK | NOT_END,
1102 /* shch */ NOT_BEGIN | BREAK | NOT_END,
1103 /* shgh */ NOT_BEGIN | BREAK | NOT_END,
1104 /* shph */ NOT_BEGIN | BREAK | NOT_END,
1105 /* shrh */ ILLEGAL_PAIR,
1106 /* shsh */ ILLEGAL_PAIR,
1107 /* shth */ NOT_BEGIN | BREAK | NOT_END,
1108 /* shwh */ ILLEGAL_PAIR,
1109 /* shqu */ NOT_BEGIN | BREAK | NOT_END,
1110 /* shck */ ILLEGAL_PAIR },
1111 {/* tha */ ANY_COMBINATION,
1112 /* thb */ NOT_BEGIN | BREAK | NOT_END,
1113 /* thc */ NOT_BEGIN | BREAK | NOT_END,
1114 /* thd */ NOT_BEGIN | BREAK | NOT_END,
1115 /* the */ ANY_COMBINATION,
1116 /* thf */ NOT_BEGIN | BREAK | NOT_END,
1117 /* thg */ NOT_BEGIN | BREAK | NOT_END,
1118 /* thh */ NOT_BEGIN | BREAK | NOT_END,
1119 /* thi */ ANY_COMBINATION,
1120 /* thj */ NOT_BEGIN | BREAK | NOT_END,
1121 /* thk */ NOT_BEGIN | BREAK | NOT_END,
1122 /* thl */ NOT_BEGIN | BREAK | NOT_END,
1123 /* thm */ NOT_BEGIN | BREAK | NOT_END,
1124 /* thn */ NOT_BEGIN | BREAK | NOT_END,
1125 /* tho */ ANY_COMBINATION,
1126 /* thp */ NOT_BEGIN | BREAK | NOT_END,
1128 /* ths */ NOT_BEGIN | END,
1129 /* tht */ NOT_BEGIN | BREAK | NOT_END,
1130 /* thu */ ANY_COMBINATION,
1131 /* thv */ NOT_BEGIN | BREAK | NOT_END,
1132 /* thw */ SUFFIX | NOT_END,
1133 /* thx */ ILLEGAL_PAIR,
1134 /* thy */ ANY_COMBINATION,
1135 /* thz */ NOT_BEGIN | BREAK | NOT_END,
1136 /* thch */ NOT_BEGIN | BREAK | NOT_END,
1137 /* thgh */ NOT_BEGIN | BREAK | NOT_END,
1138 /* thph */ NOT_BEGIN | BREAK | NOT_END,
1139 /* thrh */ ILLEGAL_PAIR,
1140 /* thsh */ NOT_BEGIN | BREAK | NOT_END,
1141 /* thth */ ILLEGAL_PAIR,
1142 /* thwh */ ILLEGAL_PAIR,
1143 /* thqu */ NOT_BEGIN | BREAK | NOT_END,
1144 /* thck */ ILLEGAL_PAIR },
1145 {/* wha */ BEGIN | NOT_END,
1146 /* whb */ ILLEGAL_PAIR,
1147 /* whc */ ILLEGAL_PAIR,
1148 /* whd */ ILLEGAL_PAIR,
1149 /* whe */ BEGIN | NOT_END,
1150 /* whf */ ILLEGAL_PAIR,
1151 /* whg */ ILLEGAL_PAIR,
1152 /* whh */ ILLEGAL_PAIR,
1153 /* whi */ BEGIN | NOT_END,
1154 /* whj */ ILLEGAL_PAIR,
1155 /* whk */ ILLEGAL_PAIR,
1156 /* whl */ ILLEGAL_PAIR,
1157 /* whm */ ILLEGAL_PAIR,
1158 /* whn */ ILLEGAL_PAIR,
1159 /* who */ BEGIN | NOT_END,
1160 /* whp */ ILLEGAL_PAIR,
1161 /* whr */ ILLEGAL_PAIR,
1162 /* whs */ ILLEGAL_PAIR,
1163 /* wht */ ILLEGAL_PAIR,
1164 /* whu */ ILLEGAL_PAIR,
1165 /* whv */ ILLEGAL_PAIR,
1166 /* whw */ ILLEGAL_PAIR,
1167 /* whx */ ILLEGAL_PAIR,
1168 /* why */ BEGIN | NOT_END,
1169 /* whz */ ILLEGAL_PAIR,
1170 /* whch */ ILLEGAL_PAIR,
1171 /* whgh */ ILLEGAL_PAIR,
1172 /* whph */ ILLEGAL_PAIR,
1173 /* whrh */ ILLEGAL_PAIR,
1174 /* whsh */ ILLEGAL_PAIR,
1175 /* whth */ ILLEGAL_PAIR,
1176 /* whwh */ ILLEGAL_PAIR,
1177 /* whqu */ ILLEGAL_PAIR,
1178 /* whck */ ILLEGAL_PAIR },
1179 {/* qua */ ANY_COMBINATION,
1180 /* qub */ ILLEGAL_PAIR,
1181 /* quc */ ILLEGAL_PAIR,
1182 /* qud */ ILLEGAL_PAIR,
1183 /* que */ ANY_COMBINATION,
1184 /* quf */ ILLEGAL_PAIR,
1185 /* qug */ ILLEGAL_PAIR,
1186 /* quh */ ILLEGAL_PAIR,
1187 /* qui */ ANY_COMBINATION,
1188 /* quj */ ILLEGAL_PAIR,
1189 /* quk */ ILLEGAL_PAIR,
1190 /* qul */ ILLEGAL_PAIR,
1191 /* qum */ ILLEGAL_PAIR,
1192 /* qun */ ILLEGAL_PAIR,
1193 /* quo */ ANY_COMBINATION,
1194 /* qup */ ILLEGAL_PAIR,
1195 /* qur */ ILLEGAL_PAIR,
1196 /* qus */ ILLEGAL_PAIR,
1197 /* qut */ ILLEGAL_PAIR,
1198 /* quu */ ILLEGAL_PAIR,
1199 /* quv */ ILLEGAL_PAIR,
1200 /* quw */ ILLEGAL_PAIR,
1201 /* qux */ ILLEGAL_PAIR,
1202 /* quy */ ILLEGAL_PAIR,
1203 /* quz */ ILLEGAL_PAIR,
1204 /* quch */ ILLEGAL_PAIR,
1205 /* qugh */ ILLEGAL_PAIR,
1206 /* quph */ ILLEGAL_PAIR,
1207 /* qurh */ ILLEGAL_PAIR,
1208 /* qush */ ILLEGAL_PAIR,
1209 /* quth */ ILLEGAL_PAIR,
1210 /* quwh */ ILLEGAL_PAIR,
1211 /* ququ */ ILLEGAL_PAIR,
1212 /* quck */ ILLEGAL_PAIR },
1213 {/* cka */ NOT_BEGIN | BREAK | NOT_END,
1214 /* ckb */ NOT_BEGIN | BREAK | NOT_END,
1215 /* ckc */ NOT_BEGIN | BREAK | NOT_END,
1216 /* ckd */ NOT_BEGIN | BREAK | NOT_END,
1217 /* cke */ NOT_BEGIN | BREAK | NOT_END,
1218 /* ckf */ NOT_BEGIN | BREAK | NOT_END,
1219 /* ckg */ NOT_BEGIN | BREAK | NOT_END,
1220 /* ckh */ NOT_BEGIN | BREAK | NOT_END,
1221 /* cki */ NOT_BEGIN | BREAK | NOT_END,
1222 /* ckj */ NOT_BEGIN | BREAK | NOT_END,
1223 /* ckk */ NOT_BEGIN | BREAK | NOT_END,
1224 /* ckl */ NOT_BEGIN | BREAK | NOT_END,
1225 /* ckm */ NOT_BEGIN | BREAK | NOT_END,
1226 /* ckn */ NOT_BEGIN | BREAK | NOT_END,
1227 /* cko */ NOT_BEGIN | BREAK | NOT_END,
1228 /* ckp */ NOT_BEGIN | BREAK | NOT_END,
1229 /* ckr */ NOT_BEGIN | BREAK | NOT_END,
1230 /* cks */ NOT_BEGIN,
1231 /* ckt */ NOT_BEGIN | BREAK | NOT_END,
1232 /* cku */ NOT_BEGIN | BREAK | NOT_END,
1233 /* ckv */ NOT_BEGIN | BREAK | NOT_END,
1234 /* ckw */ NOT_BEGIN | BREAK | NOT_END,
1235 /* ckx */ ILLEGAL_PAIR,
1236 /* cky */ NOT_BEGIN,
1237 /* ckz */ NOT_BEGIN | BREAK | NOT_END,
1238 /* ckch */ NOT_BEGIN | BREAK | NOT_END,
1239 /* ckgh */ NOT_BEGIN | BREAK | NOT_END,
1240 /* ckph */ NOT_BEGIN | BREAK | NOT_END,
1241 /* ckrh */ ILLEGAL_PAIR,
1242 /* cksh */ NOT_BEGIN | BREAK | NOT_END,
1243 /* ckth */ NOT_BEGIN | BREAK | NOT_END,
1244 /* ckwh */ ILLEGAL_PAIR,
1245 /* ckqu */ NOT_BEGIN | BREAK | NOT_END,
1246 /* ckck */ ILLEGAL_PAIR}
1250 ** gen_pron_pass will generate a Random word and place it in the
1251 ** buffer word. Also, the hyphenated word will be placed into
1252 ** the buffer hyphenated_word. Both word and hyphenated_word must
1253 ** be pre-allocated. The words generated will have sizes between
1254 ** minlen and maxlen. If restrict is TRUE, words will not be generated that
1255 ** appear as login names or as entries in the on-line dictionary.
1256 ** This algorithm was initially worded out by Morrie Gasser in 1975.
1257 ** Any changes here are minimal so that as many word combinations
1258 ** can be produced as possible (and thus keep the words Random).
1259 ** The seed is used on first use of the routine.
1260 ** The length of the unhyphenated word is returned, or -1 if there
1261 ** were an error (length settings are wrong or dictionary checking
1262 ** could not be done.
1265 gen_pron_pass (char *word, char *hyphenated_word, USHORT minlen,
1266 USHORT maxlen, unsigned int pass_mode)
1272 * Check for minlen>maxlen. This is an error.
1273 * and a length of 0.
1275 if (minlen > maxlen || minlen > APG_MAX_PASSWORD_LENGTH ||
1276 maxlen > APG_MAX_PASSWORD_LENGTH)
1279 * Check for zero length words. This is technically not an error,
1280 * so we take the short cut and return a null word and a length of 0.
1285 hyphenated_word[0] = '\0';
1292 pwlen = gen_word (word, hyphenated_word, get_random (minlen, maxlen), pass_mode);
1298 * This is the routine that returns a Random word -- as
1299 * yet unchecked against the passwd file or the dictionary.
1300 * It collects Random syllables until a predetermined
1301 * word length is found. If a retry threshold is reached,
1302 * another word is tried. Given that the Random number
1303 * generator is uniformly distributed, eventually a word
1304 * will be found if the retry limit is adequately large enough.
1307 gen_word (char *word, char *hyphenated_word, USHORT pwlen, unsigned int pass_mode)
1310 USHORT syllable_length;
1312 char *syllable_for_hyph;
1313 USHORT *syllable_units;
1317 USHORT syllable_size;
1319 int ch_flag = FALSE;
1323 * Keep count of retries.
1328 * The length of the word in characters.
1333 * The length of the word in character units (each of which is one or
1334 * two characters long.
1339 * Initialize the array storing the word units. Since we know the
1340 * length of the word, we only need one of that length. This method is
1341 * preferable to a static array, since it allows us flexibility in
1342 * choosing arbitrarily long word lengths. Since a word can contain one
1343 * syllable, we should make syllable_units, the array holding the
1344 * analogous units for an individual syllable, the same length. No
1345 * explicit rule limits the length of syllables, but digram rules and
1346 * heuristics do so indirectly.
1348 if ( (word_units = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL ||
1349 (syllable_units = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL ||
1350 (new_syllable = (char *) calloc (sizeof (USHORT), pwlen+1)) ==NULL ||
1351 (syllable_for_hyph = (char *) calloc (sizeof(char), 20))==NULL)
1355 * Find syllables until the entire word is constructed.
1357 while (word_length < pwlen)
1360 * Get the syllable and find its length.
1362 (void) gen_syllable (new_syllable, pwlen - word_length, syllable_units, &syllable_size);
1363 syllable_length = strlen (new_syllable);
1366 * Append the syllable units to the word units.
1368 for (word_place = 0; word_place <= syllable_size; word_place++)
1369 word_units[word_size + word_place] = syllable_units[word_place];
1370 word_size += syllable_size + 1;
1373 * If the word has been improperly formed, throw out
1374 * the syllable. The checks performed here are those
1375 * that must be formed on a word basis. The other
1376 * tests are performed entirely within the syllable.
1377 * Otherwise, append the syllable to the word and
1378 * append the syllable to the hyphenated version of
1381 if (improper_word (word_units, word_size) ||
1382 ((word_length == 0) && have_initial_y (syllable_units, syllable_size)) ||
1383 ((word_length + syllable_length == pwlen) && have_final_split (syllable_units, syllable_size)))
1384 word_size -= syllable_size + 1;
1387 if (word_length == 0)
1390 ** Modify syllable for numeric or capital symbols required
1391 ** Should be done after word quality check.
1394 if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && dsd == 0)
1396 numerize(new_syllable);
1399 if ( ((pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1))
1401 specialize(new_syllable);
1404 if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE))
1405 capitalize(new_syllable);
1408 (void) strcpy (word, new_syllable);
1409 if (syllable_length == 1)
1411 symb2name(new_syllable, syllable_for_hyph);
1412 (void) strcpy (hyphenated_word, syllable_for_hyph);
1416 (void) strcpy (hyphenated_word, new_syllable);
1418 (void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1));
1419 (void)memset ( (void *)syllable_for_hyph, 0, 20);
1424 ** Modify syllable for numeric or capital symbols required
1425 ** Should be done after word quality check.
1428 if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && (dsd == 0))
1430 numerize(new_syllable);
1433 if ( ( (pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1))
1435 specialize(new_syllable);
1438 if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE))
1439 capitalize(new_syllable);
1442 (void) strcat (word, new_syllable);
1443 (void) strcat (hyphenated_word, "-");
1444 if (syllable_length == 1)
1446 symb2name(new_syllable, syllable_for_hyph);
1447 (void) strcat (hyphenated_word, syllable_for_hyph);
1451 (void) strcat (hyphenated_word, new_syllable);
1453 (void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1));
1454 (void)memset ( (void *)syllable_for_hyph, 0, 20);
1456 word_length += syllable_length;
1460 * Keep track of the times we have tried to get
1461 * syllables. If we have exceeded the threshold,
1462 * reinitialize the pwlen and word_size variables, clear
1463 * out the word arrays, and start from scratch.
1466 if (tries > MAX_RETRIES)
1471 (void) strcpy (word, "");
1472 (void) strcpy (hyphenated_word, "");
1477 * The units arrays and syllable storage are internal to this
1478 * routine. Since the caller has no need for them, we
1479 * release the space.
1481 free ((char *) new_syllable);
1482 free ((char *) syllable_units);
1483 free ((char *) word_units);
1484 free ((char *) syllable_for_hyph);
1486 return ((int) word_length);
1492 * Check that the word does not contain illegal combinations
1493 * that may span syllables. Specifically, these are:
1494 * 1. An illegal pair of units between syllables.
1495 * 2. Three consecutive vowel units.
1496 * 3. Three consecutive consonant units.
1497 * The checks are made against units (1 or 2 letters), not against
1498 * the individual letters, so three consecutive units can have
1499 * the length of 6 at most.
1502 improper_word (USHORT *units, USHORT word_size)
1509 for (unit_count = 0; !failure && (unit_count < word_size);
1513 * Check for ILLEGAL_PAIR. This should have been caught
1514 * for units within a syllable, but in some cases it
1515 * would have gone unnoticed for units between syllables
1516 * (e.g., when saved_unit's in gen_syllable() were not
1519 if ((unit_count != 0) &&
1520 (digram[units[unit_count - 1]][units[unit_count]] &
1525 * Check for consecutive vowels or consonants. Because
1526 * the initial y of a syllable is treated as a consonant
1527 * rather than as a vowel, we exclude y from the first
1528 * vowel in the vowel test. The only problem comes when
1529 * y ends a syllable and two other vowels start the next,
1530 * like fly-oint. Since such words are still
1531 * pronounceable, we accept this.
1533 if (!failure && (unit_count >= 2))
1538 if ((((rules[units[unit_count - 2]].flags & VOWEL) &&
1539 !(rules[units[unit_count - 2]].flags &
1540 ALTERNATE_VOWEL)) &&
1541 (rules[units[unit_count - 1]].flags & VOWEL) &&
1542 (rules[units[unit_count]].flags & VOWEL)) ||
1546 (!(rules[units[unit_count - 2]].flags & VOWEL) &&
1547 !(rules[units[unit_count - 1]].flags & VOWEL) &&
1548 !(rules[units[unit_count]].flags & VOWEL)))
1558 * Treating y as a vowel is sometimes a problem. Some words
1559 * get formed that look irregular. One special group is when
1560 * y starts a word and is the only vowel in the first syllable.
1561 * The word ycl is one example. We discard words like these.
1564 have_initial_y (USHORT *units, USHORT unit_size)
1568 USHORT normal_vowel_count;
1571 normal_vowel_count = 0;
1573 for (unit_count = 0; unit_count <= unit_size; unit_count++)
1577 if (rules[units[unit_count]].flags & VOWEL)
1582 * Count the vowels that are not: 1. y, 2. at the start of
1585 if (!(rules[units[unit_count]].flags & ALTERNATE_VOWEL) ||
1587 normal_vowel_count++;
1590 return ((vowel_count <= 1) && (normal_vowel_count == 0));
1595 * Besides the problem with the letter y, there is one with
1596 * a silent e at the end of words, like face or nice. We
1597 * allow this silent e, but we do not allow it as the only
1598 * vowel at the end of the word or syllables like ble will
1602 have_final_split (USHORT *units, USHORT unit_size)
1610 * Count all the vowels in the word.
1612 for (unit_count = 0; unit_count <= unit_size; unit_count++)
1613 if (rules[units[unit_count]].flags & VOWEL)
1617 * Return TRUE iff the only vowel was e, found at the end if the
1620 return ((vowel_count == 1) &&
1621 (rules[units[unit_size]].flags & NO_FINAL_SPLIT));
1626 * Generate next unit to password, making sure that it follows
1628 * 1. Each syllable must contain exactly 1 or 2 consecutive
1629 * vowels, where y is considered a vowel.
1630 * 2. Syllable end is determined as follows:
1631 * a. Vowel is generated and previous unit is a
1632 * consonant and syllable already has a vowel. In
1633 * this case, new syllable is started and already
1635 * b. A pair determined to be a "break" pair is encountered.
1636 * In this case new syllable is started with second unit
1638 * c. End of password is encountered.
1639 * d. "begin" pair is encountered legally. New syllable is
1640 * started with this pair.
1641 * e. "end" pair is legally encountered. New syllable has
1643 * 3. Try generating another unit if:
1644 * a. third consecutive vowel and not y.
1645 * b. "break" pair generated but no vowel yet in current
1646 * or previous 2 units are "not_end".
1647 * c. "begin" pair generated but no vowel in syllable
1648 * preceding begin pair, or both previous 2 pairs are
1649 * designated "not_end".
1650 * d. "end" pair generated but no vowel in current syllable
1652 * e. "not_begin" pair generated but new syllable must
1653 * begin (because previous syllable ended as defined in
1655 * f. vowel is generated and 2a is satisfied, but no syllable
1656 * break is possible in previous 3 pairs.
1657 * g. Second and third units of syllable must begin, and
1658 * first unit is "alternate_vowel".
1661 gen_syllable (char *syllable, USHORT pwlen, USHORT *units_in_syllable,
1662 USHORT *syllable_length)
1665 SHORT current_unit = 0;
1666 USHORT vowel_count = 0;
1667 boolean rule_broken;
1669 boolean want_another_unit;
1671 USHORT last_unit = 0;
1672 SHORT length_left = 0;
1673 USHORT hold_saved_unit = 0;
1674 static USHORT saved_unit;
1675 static USHORT saved_pair[2];
1678 * This is needed if the saved_unit is tries and the syllable then
1679 * discarded because of the retry limit. Since the saved_unit is OK and
1680 * fits in nicely with the preceding syllable, we will always use it.
1682 hold_saved_unit = saved_unit;
1685 * Loop until valid syllable is found.
1690 * Try for a new syllable. Initialize all pertinent
1691 * syllable variables.
1694 saved_unit = hold_saved_unit;
1695 (void) strcpy (syllable, "");
1698 length_left = (short int) pwlen;
1699 want_another_unit = TRUE;
1702 * This loop finds all the units for the syllable.
1709 * This loop continues until a valid unit is found for the
1710 * current position within the syllable.
1715 * If there are saved_unit's from the previous
1716 * syllable, use them up first.
1718 if (saved_unit != 0)
1721 * If there were two saved units, the first is
1722 * guaranteed (by checks performed in the previous
1723 * syllable) to be valid. We ignore the checks
1724 * and place it in this syllable manually.
1726 if (saved_unit == 2)
1728 units_in_syllable[0] = saved_pair[1];
1729 if (rules[saved_pair[1]].flags & VOWEL)
1732 (void) strcpy (syllable, rules[saved_pair[1]].unit_code);
1733 length_left -= strlen (syllable);
1737 * The unit becomes the last unit checked in the
1738 * previous syllable.
1740 unit = saved_pair[0];
1743 * The saved units have been used. Do not try to
1744 * reuse them in this syllable (unless this particular
1745 * syllable is rejected at which point we start to rebuild
1746 * it with these same saved units.
1752 * If we don't have to scoff the saved units,
1753 * we generate a Random one. If we know it has
1754 * to be a vowel, we get one rather than looping
1755 * through until one shows up.
1758 unit = random_unit (VOWEL);
1760 unit = random_unit (NO_SPECIAL_RULE);
1761 length_left -= (short int) strlen (rules[unit].unit_code);
1764 * Prevent having a word longer than expected.
1766 if (length_left < 0)
1769 rule_broken = FALSE;
1772 * First unit of syllable. This is special because the
1773 * digram tests require 2 units and we don't have that yet.
1774 * Nevertheless, we can perform some checks.
1776 if (current_unit == 0)
1779 * If the shouldn't begin a syllable, don't
1782 if (rules[unit].flags & NOT_BEGIN_SYLLABLE)
1786 * If this is the last unit of a word,
1787 * we have a one unit syllable. Since each
1788 * syllable must have a vowel, we make sure
1789 * the unit is a vowel. Otherwise, we
1792 if (length_left == 0)
1794 if (rules[unit].flags & VOWEL)
1795 want_another_unit = FALSE;
1803 * There are some digram tests that are
1804 * universally true. We test them out.
1808 * Reject ILLEGAL_PAIRS of units.
1810 if ((ALLOWED (ILLEGAL_PAIR)) ||
1813 * Reject units that will be split between syllables
1814 * when the syllable has no vowels in it.
1816 (ALLOWED (BREAK) && (vowel_count == 0)) ||
1819 * Reject a unit that will end a syllable when no
1820 * previous unit was a vowel and neither is this one.
1822 (ALLOWED (END) && (vowel_count == 0) &&
1823 !(rules[unit].flags & VOWEL)))
1826 if (current_unit == 1)
1829 * Reject the unit if we are at te starting digram of
1830 * a syllable and it does not fit.
1832 if (ALLOWED (NOT_BEGIN))
1838 * We are not at the start of a syllable.
1839 * Save the previous unit for later tests.
1841 last_unit = units_in_syllable[current_unit - 1];
1844 * Do not allow syllables where the first letter is y
1845 * and the next pair can begin a syllable. This may
1846 * lead to splits where y is left alone in a syllable.
1847 * Also, the combination does not sound to good even
1850 if (((current_unit == 2) &&
1851 (ALLOWED (BEGIN)) &&
1852 (rules[units_in_syllable[0]].flags &
1853 ALTERNATE_VOWEL)) ||
1856 * If this is the last unit of a word, we should
1857 * reject any digram that cannot end a syllable.
1859 (ALLOWED (NOT_END) &&
1860 (length_left == 0)) ||
1863 * Reject the unit if the digram it forms wants
1864 * to break the syllable, but the resulting
1865 * digram that would end the syllable is not
1866 * allowed to end a syllable.
1869 (digram[units_in_syllable
1875 * Reject the unit if the digram it forms
1876 * expects a vowel preceding it and there is
1879 (ALLOWED (PREFIX) &&
1880 !(rules[units_in_syllable
1881 [current_unit - 2]].flags &
1886 * The following checks occur when the current unit
1887 * is a vowel and we are not looking at a word ending
1891 (rules[unit].flags & VOWEL) &&
1892 ((length_left > 0) ||
1893 !(rules[last_unit].flags &
1897 * Don't allow 3 consecutive vowels in a
1898 * syllable. Although some words formed like this
1899 * are OK, like beau, most are not.
1901 if ((vowel_count > 1) &&
1902 (rules[last_unit].flags & VOWEL))
1906 * Check for the case of
1907 * vowels-consonants-vowel, which is only
1908 * legal if the last vowel is an e and we are
1909 * the end of the word (wich is not
1910 * happening here due to a previous check.
1912 if ((vowel_count != 0) &&
1913 !(rules[last_unit].flags & VOWEL))
1916 * Try to save the vowel for the next
1917 * syllable, but if the syllable left here
1918 * is not proper (i.e., the resulting last
1919 * digram cannot legally end it), just
1920 * discard it and try for another.
1922 if (digram[units_in_syllable
1930 saved_pair[0] = unit;
1931 want_another_unit = FALSE;
1938 * The unit picked and the digram formed are legal.
1939 * We now determine if we can end the syllable. It may,
1940 * in some cases, mean the last unit(s) may be deferred to
1941 * the next syllable. We also check here to see if the
1942 * digram formed expects a vowel to follow.
1944 if (!rule_broken && want_another_unit)
1947 * This word ends in a silent e.
1949 /******/ if (((vowel_count != 0) &&
1950 (rules[unit].flags & NO_FINAL_SPLIT) &&
1951 (length_left == 0) &&
1952 !(rules[last_unit].flags & VOWEL)) ||
1955 * This syllable ends either because the digram
1956 * is an END pair or we would otherwise exceed
1957 * the length of the word.
1959 (ALLOWED (END) || (length_left == 0)))
1961 want_another_unit = FALSE;
1965 * Since we have a vowel in the syllable
1966 * already, if the digram calls for the end of the
1967 * syllable, we can legally split it off. We also
1968 * make sure that we are not at the end of the
1969 * dangerous because that syllable may not have
1970 * vowels, or it may not be a legal syllable end,
1971 * and the retrying mechanism will loop infinitely
1972 * with the same digram.
1974 if ((vowel_count != 0) && (length_left > 0))
1977 * If we must begin a syllable, we do so if
1978 * the only vowel in THIS syllable is not part
1979 * of the digram we are pushing to the next
1982 if (ALLOWED (BEGIN) &&
1983 (current_unit > 1) &&
1984 !((vowel_count == 1) &&
1985 (rules[last_unit].flags & VOWEL)))
1988 saved_pair[0] = unit;
1989 saved_pair[1] = last_unit;
1990 want_another_unit = FALSE;
1993 if (ALLOWED (BREAK))
1996 saved_pair[0] = unit;
1997 want_another_unit = FALSE;
2001 if (ALLOWED (SUFFIX))
2011 * If this unit was illegal, redetermine the amount of
2012 * letters left to go in the word.
2015 length_left += (short int) strlen (rules[unit].unit_code);
2017 while (rule_broken && (tries <= MAX_RETRIES));
2022 if (tries <= MAX_RETRIES)
2025 * If the unit were a vowel, count it in.
2026 * However, if the unit were a y and appear
2027 * at the start of the syllable, treat it
2028 * like a constant (so that words like year can
2029 * appear and not conflict with the 3 consecutive
2032 if ((rules[unit].flags & VOWEL) &&
2033 ((current_unit > 0) ||
2034 !(rules[unit].flags & ALTERNATE_VOWEL)))
2038 * If a unit or units were to be saved, we must
2039 * adjust the syllable formed. Otherwise, we
2040 * append the current unit to the syllable.
2045 units_in_syllable[current_unit] = unit;
2046 (void) strcat (syllable, rules[unit].unit_code);
2052 (void) strcpy (&syllable[strlen (syllable) -
2053 strlen (rules[last_unit].unit_code)],"");
2054 length_left += (short int) strlen (rules[last_unit].unit_code);
2061 * Whoops! Too many tries. We set rule_broken so we can
2062 * loop in the outer loop and try another syllable.
2067 * ...and the syllable length grows.
2069 *syllable_length = current_unit;
2073 while ((tries <= MAX_RETRIES) && want_another_unit);
2075 while (rule_broken ||
2076 illegal_placement (units_in_syllable, *syllable_length));
2083 * This routine goes through an individual syllable and checks
2084 * for illegal combinations of letters that go beyond looking
2085 * at digrams. We look at things like 3 consecutive vowels or
2086 * consonants, or syllables with consonants between vowels (unless
2087 * one of them is the final silent e).
2090 illegal_placement (USHORT *units, USHORT pwlen)
2099 for (unit_count = 0; !failure && (unit_count <= pwlen);
2102 if (unit_count >= 1)
2105 * Don't allow vowels to be split with consonants in
2106 * a single syllable. If we find such a combination
2107 * (except for the silent e) we have to discard the
2110 if ((!(rules[units[unit_count - 1]].flags & VOWEL) &&
2111 (rules[units[unit_count]].flags & VOWEL) &&
2112 !((rules[units[unit_count]].flags & NO_FINAL_SPLIT) &&
2113 (unit_count == pwlen)) && (vowel_count != 0)) ||
2115 * Perform these checks when we have at least 3 units.
2117 ((unit_count >= 2) &&
2120 * Disallow 3 consecutive consonants.
2122 ((!(rules[units[unit_count - 2]].flags & VOWEL) &&
2123 !(rules[units[unit_count - 1]].flags &
2125 !(rules[units[unit_count]].flags &
2129 * Disallow 3 consecutive vowels, where the first is
2132 (((rules[units[unit_count - 2]].flags &
2134 !((rules[units[0]].flags &
2136 (unit_count == 2))) &&
2137 (rules[units[unit_count - 1]].flags &
2139 (rules[units[unit_count]].flags &
2145 * Count the vowels in the syllable. As mentioned somewhere
2146 * above, exclude the initial y of a syllable. Instead,
2147 * treat it as a consonant.
2149 if ((rules[units[unit_count]].flags & VOWEL) &&
2150 !((rules[units[0]].flags & ALTERNATE_VOWEL) &&
2151 (unit_count == 0) && (pwlen != 0)))
2161 * This is the standard Random unit generating routine for
2162 * gen_syllable(). It does not reference the digrams, but
2163 * assumes that it contains 34 units in a particular order.
2164 * This routine attempts to return unit indexes with a distribution
2165 * approaching that of the distribution of the 34 units in
2166 * English. In order to do this, a Random number (supposedly
2167 * uniformly distributed) is used to do a table lookup into an
2168 * array containing unit indices. There are 211 entries in
2169 * the array for the random_unit entry point. The probability
2170 * of a particular unit being generated is equal to the
2171 * fraction of those 211 entries that contain that unit index.
2172 * For example, the letter `a' is unit number 1. Since unit
2173 * index 1 appears 10 times in the array, the probability of
2174 * selecting an `a' is 10/211.
2176 * Changes may be made to the digram table without affect to this
2177 * procedure providing the letter-to-number correspondence of
2178 * the units does not change. Likewise, the distribution of the
2179 * 34 units may be altered (and the array size may be changed)
2180 * in this procedure without affecting the digram table or any other
2181 * programs using the Random_word subroutine.
2183 static USHORT numbers[] =
2185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2186 1, 1, 1, 1, 1, 1, 1, 1,
2187 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2188 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2189 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2190 5, 5, 5, 5, 5, 5, 5, 5,
2191 6, 6, 6, 6, 6, 6, 6, 6,
2193 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
2194 9, 9, 9, 9, 9, 9, 9, 9,
2195 10, 10, 10, 10, 10, 10, 10, 10,
2196 11, 11, 11, 11, 11, 11,
2197 12, 12, 12, 12, 12, 12,
2198 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2199 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2200 15, 15, 15, 15, 15, 15,
2201 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2202 17, 17, 17, 17, 17, 17, 17, 17,
2203 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
2204 19, 19, 19, 19, 19, 19,
2205 20, 20, 20, 20, 20, 20, 20, 20,
2206 21, 21, 21, 21, 21, 21, 21, 21,
2208 23, 23, 23, 23, 23, 23, 23, 23,
2223 * This structure has a typical English frequency of vowels.
2224 * The value of an entry is the vowel position (a=0, e=4, i=8,
2225 * o=14, u=19, y=23) in the rules array. The number of times
2226 * the value appears is the frequency. Thus, the letter "a"
2227 * is assumed to appear 2/12 = 1/6 of the time. This array
2228 * may be altered if better data is obtained. The routines that
2229 * use vowel_numbers will adjust to the size difference
2232 static USHORT vowel_numbers[] =
2234 0, 0, 4, 4, 4, 8, 8, 14, 14, 19, 19, 23
2239 * Select a unit (a letter or a consonant group). If a vowel is
2240 * expected, use the vowel_numbers array rather than looping through
2241 * the numbers array until a vowel is found.
2244 random_unit (USHORT type)
2249 * Sometimes, we are asked to explicitly get a vowel (i.e., if
2250 * a digram pair expects one following it). This is a shortcut
2251 * to do that and avoid looping with rejected consonants.
2254 number = vowel_numbers[get_random (0, (sizeof (vowel_numbers) / sizeof (USHORT))-1)];
2257 * Get any letter according to the English distribution.
2259 number = numbers[get_random (0, (sizeof (numbers) / sizeof (USHORT))-1)];
2266 ** This routine should return a uniformly distributed Random number between
2267 ** minlen and maxlen inclusive. The Electronic Code Book form of CAST is
2268 ** used to produce the Random number. The inputs to CAST are the old pass-
2269 ** word and a pseudoRandom key generated according to the procedure out-
2270 ** lined in Appendix C of ANSI X9.17.
2275 ** USHORT - random number
2281 get_random (USHORT minlen, USHORT maxlen)
2284 ret = minlen + (USHORT) randint ((int) (maxlen - minlen + 1));