You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2286 lines
78 KiB
2286 lines
78 KiB
/*
|
|
** This module uses code from the NIST implementation of FIPS-181,
|
|
** but the algorythm is CHANGED and I think that I CAN
|
|
** copyright it. See copiright notes below.
|
|
*/
|
|
|
|
/*
|
|
** Copyright (c) 1999, 2000, 2001, 2002, 2003
|
|
** Adel I. Mirzazhanov. All rights reserved
|
|
**
|
|
** Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions
|
|
** are met:
|
|
**
|
|
** 1.Redistributions of source code must retain the above copyright notice,
|
|
** this list of conditions and the following disclaimer.
|
|
** 2.Redistributions in binary form must reproduce the above copyright
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
** documentation and/or other materials provided with the distribution.
|
|
** 3.The name of the author may not be used to endorse or promote products
|
|
** derived from this software without specific prior written permission.
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "random.h"
|
|
|
|
#include "pronpass.h"
|
|
#include "randpass.h"
|
|
#include "convert.h"
|
|
|
|
struct unit
|
|
{
|
|
char unit_code[5];
|
|
USHORT flags;
|
|
};
|
|
|
|
static struct unit rules[] =
|
|
{ {"a", VOWEL},
|
|
{"b", NO_SPECIAL_RULE},
|
|
{"c", NO_SPECIAL_RULE},
|
|
{"d", NO_SPECIAL_RULE},
|
|
{"e", NO_FINAL_SPLIT | VOWEL},
|
|
{"f", NO_SPECIAL_RULE},
|
|
{"g", NO_SPECIAL_RULE},
|
|
{"h", NO_SPECIAL_RULE},
|
|
{"i", VOWEL},
|
|
{"j", NO_SPECIAL_RULE},
|
|
{"k", NO_SPECIAL_RULE},
|
|
{"l", NO_SPECIAL_RULE},
|
|
{"m", NO_SPECIAL_RULE},
|
|
{"n", NO_SPECIAL_RULE},
|
|
{"o", VOWEL},
|
|
{"p", NO_SPECIAL_RULE},
|
|
{"r", NO_SPECIAL_RULE},
|
|
{"s", NO_SPECIAL_RULE},
|
|
{"t", NO_SPECIAL_RULE},
|
|
{"u", VOWEL},
|
|
{"v", NO_SPECIAL_RULE},
|
|
{"w", NO_SPECIAL_RULE},
|
|
{"x", NOT_BEGIN_SYLLABLE},
|
|
{"y", ALTERNATE_VOWEL | VOWEL},
|
|
{"z", NO_SPECIAL_RULE},
|
|
{"ch", NO_SPECIAL_RULE},
|
|
{"gh", NO_SPECIAL_RULE},
|
|
{"ph", NO_SPECIAL_RULE},
|
|
{"rh", NO_SPECIAL_RULE},
|
|
{"sh", NO_SPECIAL_RULE},
|
|
{"th", NO_SPECIAL_RULE},
|
|
{"wh", NO_SPECIAL_RULE},
|
|
{"qu", NO_SPECIAL_RULE},
|
|
{"ck", NOT_BEGIN_SYLLABLE}
|
|
};
|
|
|
|
static int digram[][RULE_SIZE] =
|
|
{
|
|
{/* aa */ ILLEGAL_PAIR,
|
|
/* ab */ ANY_COMBINATION,
|
|
/* ac */ ANY_COMBINATION,
|
|
/* ad */ ANY_COMBINATION,
|
|
/* ae */ ILLEGAL_PAIR,
|
|
/* af */ ANY_COMBINATION,
|
|
/* ag */ ANY_COMBINATION,
|
|
/* ah */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ai */ ANY_COMBINATION,
|
|
/* aj */ ANY_COMBINATION,
|
|
/* ak */ ANY_COMBINATION,
|
|
/* al */ ANY_COMBINATION,
|
|
/* am */ ANY_COMBINATION,
|
|
/* an */ ANY_COMBINATION,
|
|
/* ao */ ILLEGAL_PAIR,
|
|
/* ap */ ANY_COMBINATION,
|
|
/* ar */ ANY_COMBINATION,
|
|
/* as */ ANY_COMBINATION,
|
|
/* at */ ANY_COMBINATION,
|
|
/* au */ ANY_COMBINATION,
|
|
/* av */ ANY_COMBINATION,
|
|
/* aw */ ANY_COMBINATION,
|
|
/* ax */ ANY_COMBINATION,
|
|
/* ay */ ANY_COMBINATION,
|
|
/* az */ ANY_COMBINATION,
|
|
/* ach */ ANY_COMBINATION,
|
|
/* agh */ ILLEGAL_PAIR,
|
|
/* aph */ ANY_COMBINATION,
|
|
/* arh */ ILLEGAL_PAIR,
|
|
/* ash */ ANY_COMBINATION,
|
|
/* ath */ ANY_COMBINATION,
|
|
/* awh */ ILLEGAL_PAIR,
|
|
/* aqu */ BREAK | NOT_END,
|
|
/* ack */ ANY_COMBINATION},
|
|
{/* ba */ ANY_COMBINATION,
|
|
/* bb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* be */ ANY_COMBINATION,
|
|
/* bf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bi */ ANY_COMBINATION,
|
|
/* bj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bl */ BEGIN | SUFFIX | NOT_END,
|
|
/* bm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bo */ ANY_COMBINATION,
|
|
/* bp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* br */ BEGIN | END,
|
|
/* bs */ NOT_BEGIN,
|
|
/* bt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bu */ ANY_COMBINATION,
|
|
/* bv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bx */ ILLEGAL_PAIR,
|
|
/* by */ ANY_COMBINATION,
|
|
/* bz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bgh */ ILLEGAL_PAIR,
|
|
/* bph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* brh */ ILLEGAL_PAIR,
|
|
/* bsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bwh */ ILLEGAL_PAIR,
|
|
/* bqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* bck */ ILLEGAL_PAIR },
|
|
{/* ca */ ANY_COMBINATION,
|
|
/* cb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ce */ ANY_COMBINATION,
|
|
/* cf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ci */ ANY_COMBINATION,
|
|
/* cj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ck */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cl */ SUFFIX | NOT_END,
|
|
/* cm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* co */ ANY_COMBINATION,
|
|
/* cp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cr */ NOT_END,
|
|
/* cs */ NOT_BEGIN | END,
|
|
/* ct */ NOT_BEGIN | PREFIX,
|
|
/* cu */ ANY_COMBINATION,
|
|
/* cv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cx */ ILLEGAL_PAIR,
|
|
/* cy */ ANY_COMBINATION,
|
|
/* cz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cch */ ILLEGAL_PAIR,
|
|
/* cgh */ ILLEGAL_PAIR,
|
|
/* cph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* crh */ ILLEGAL_PAIR,
|
|
/* csh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cwh */ ILLEGAL_PAIR,
|
|
/* cqu */ NOT_BEGIN | SUFFIX | NOT_END,
|
|
/* cck */ ILLEGAL_PAIR},
|
|
{/* da */ ANY_COMBINATION,
|
|
/* db */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dd */ NOT_BEGIN,
|
|
/* de */ ANY_COMBINATION,
|
|
/* df */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* di */ ANY_COMBINATION,
|
|
/* dj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* do */ ANY_COMBINATION,
|
|
/* dp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dr */ BEGIN | NOT_END,
|
|
/* ds */ NOT_BEGIN | END,
|
|
/* dt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* du */ ANY_COMBINATION,
|
|
/* dv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dx */ ILLEGAL_PAIR,
|
|
/* dy */ ANY_COMBINATION,
|
|
/* dz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* drh */ ILLEGAL_PAIR,
|
|
/* dsh */ NOT_BEGIN | NOT_END,
|
|
/* dth */ NOT_BEGIN | PREFIX,
|
|
/* dwh */ ILLEGAL_PAIR,
|
|
/* dqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* dck */ ILLEGAL_PAIR },
|
|
{/* ea */ ANY_COMBINATION,
|
|
/* eb */ ANY_COMBINATION,
|
|
/* ec */ ANY_COMBINATION,
|
|
/* ed */ ANY_COMBINATION,
|
|
/* ee */ ANY_COMBINATION,
|
|
/* ef */ ANY_COMBINATION,
|
|
/* eg */ ANY_COMBINATION,
|
|
/* eh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ei */ NOT_END,
|
|
/* ej */ ANY_COMBINATION,
|
|
/* ek */ ANY_COMBINATION,
|
|
/* el */ ANY_COMBINATION,
|
|
/* em */ ANY_COMBINATION,
|
|
/* en */ ANY_COMBINATION,
|
|
/* eo */ BREAK,
|
|
/* ep */ ANY_COMBINATION,
|
|
/* er */ ANY_COMBINATION,
|
|
/* es */ ANY_COMBINATION,
|
|
/* et */ ANY_COMBINATION,
|
|
/* eu */ ANY_COMBINATION,
|
|
/* ev */ ANY_COMBINATION,
|
|
/* ew */ ANY_COMBINATION,
|
|
/* ex */ ANY_COMBINATION,
|
|
/* ey */ ANY_COMBINATION,
|
|
/* ez */ ANY_COMBINATION,
|
|
/* ech */ ANY_COMBINATION,
|
|
/* egh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* eph */ ANY_COMBINATION,
|
|
/* erh */ ILLEGAL_PAIR,
|
|
/* esh */ ANY_COMBINATION,
|
|
/* eth */ ANY_COMBINATION,
|
|
/* ewh */ ILLEGAL_PAIR,
|
|
/* equ */ BREAK | NOT_END,
|
|
/* eck */ ANY_COMBINATION },
|
|
{/* fa */ ANY_COMBINATION,
|
|
/* fb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fe */ ANY_COMBINATION,
|
|
/* ff */ NOT_BEGIN,
|
|
/* fg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fi */ ANY_COMBINATION,
|
|
/* fj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fl */ BEGIN | SUFFIX | NOT_END,
|
|
/* fm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fo */ ANY_COMBINATION,
|
|
/* fp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fr */ BEGIN | NOT_END,
|
|
/* fs */ NOT_BEGIN,
|
|
/* ft */ NOT_BEGIN,
|
|
/* fu */ ANY_COMBINATION,
|
|
/* fv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fx */ ILLEGAL_PAIR,
|
|
/* fy */ NOT_BEGIN,
|
|
/* fz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* frh */ ILLEGAL_PAIR,
|
|
/* fsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fwh */ ILLEGAL_PAIR,
|
|
/* fqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* fck */ ILLEGAL_PAIR },
|
|
{/* ga */ ANY_COMBINATION,
|
|
/* gb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ge */ ANY_COMBINATION,
|
|
/* gf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gg */ NOT_BEGIN,
|
|
/* gh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gi */ ANY_COMBINATION,
|
|
/* gj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gk */ ILLEGAL_PAIR,
|
|
/* gl */ BEGIN | SUFFIX | NOT_END,
|
|
/* gm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* go */ ANY_COMBINATION,
|
|
/* gp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gr */ BEGIN | NOT_END,
|
|
/* gs */ NOT_BEGIN | END,
|
|
/* gt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gu */ ANY_COMBINATION,
|
|
/* gv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gx */ ILLEGAL_PAIR,
|
|
/* gy */ NOT_BEGIN,
|
|
/* gz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ggh */ ILLEGAL_PAIR,
|
|
/* gph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* grh */ ILLEGAL_PAIR,
|
|
/* gsh */ NOT_BEGIN,
|
|
/* gth */ NOT_BEGIN,
|
|
/* gwh */ ILLEGAL_PAIR,
|
|
/* gqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* gck */ ILLEGAL_PAIR },
|
|
{/* ha */ ANY_COMBINATION,
|
|
/* hb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* he */ ANY_COMBINATION,
|
|
/* hf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hh */ ILLEGAL_PAIR,
|
|
/* hi */ ANY_COMBINATION,
|
|
/* hj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ho */ ANY_COMBINATION,
|
|
/* hp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hs */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ht */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hu */ ANY_COMBINATION,
|
|
/* hv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hx */ ILLEGAL_PAIR,
|
|
/* hy */ ANY_COMBINATION,
|
|
/* hz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hrh */ ILLEGAL_PAIR,
|
|
/* hsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hwh */ ILLEGAL_PAIR,
|
|
/* hqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* hck */ ILLEGAL_PAIR },
|
|
{/* ia */ ANY_COMBINATION,
|
|
/* ib */ ANY_COMBINATION,
|
|
/* ic */ ANY_COMBINATION,
|
|
/* id */ ANY_COMBINATION,
|
|
/* ie */ NOT_BEGIN,
|
|
/* if */ ANY_COMBINATION,
|
|
/* ig */ ANY_COMBINATION,
|
|
/* ih */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ii */ ILLEGAL_PAIR,
|
|
/* ij */ ANY_COMBINATION,
|
|
/* ik */ ANY_COMBINATION,
|
|
/* il */ ANY_COMBINATION,
|
|
/* im */ ANY_COMBINATION,
|
|
/* in */ ANY_COMBINATION,
|
|
/* io */ BREAK,
|
|
/* ip */ ANY_COMBINATION,
|
|
/* ir */ ANY_COMBINATION,
|
|
/* is */ ANY_COMBINATION,
|
|
/* it */ ANY_COMBINATION,
|
|
/* iu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* iv */ ANY_COMBINATION,
|
|
/* iw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ix */ ANY_COMBINATION,
|
|
/* iy */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* iz */ ANY_COMBINATION,
|
|
/* ich */ ANY_COMBINATION,
|
|
/* igh */ NOT_BEGIN,
|
|
/* iph */ ANY_COMBINATION,
|
|
/* irh */ ILLEGAL_PAIR,
|
|
/* ish */ ANY_COMBINATION,
|
|
/* ith */ ANY_COMBINATION,
|
|
/* iwh */ ILLEGAL_PAIR,
|
|
/* iqu */ BREAK | NOT_END,
|
|
/* ick */ ANY_COMBINATION },
|
|
{/* ja */ ANY_COMBINATION,
|
|
/* jb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* je */ ANY_COMBINATION,
|
|
/* jf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jg */ ILLEGAL_PAIR,
|
|
/* jh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ji */ ANY_COMBINATION,
|
|
/* jj */ ILLEGAL_PAIR,
|
|
/* jk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jo */ ANY_COMBINATION,
|
|
/* jp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* js */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ju */ ANY_COMBINATION,
|
|
/* jv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jx */ ILLEGAL_PAIR,
|
|
/* jy */ NOT_BEGIN,
|
|
/* jz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jrh */ ILLEGAL_PAIR,
|
|
/* jsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jwh */ ILLEGAL_PAIR,
|
|
/* jqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* jck */ ILLEGAL_PAIR },
|
|
{/* ka */ ANY_COMBINATION,
|
|
/* kb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ke */ ANY_COMBINATION,
|
|
/* kf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ki */ ANY_COMBINATION,
|
|
/* kj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kl */ SUFFIX | NOT_END,
|
|
/* km */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kn */ BEGIN | SUFFIX | NOT_END,
|
|
/* ko */ ANY_COMBINATION,
|
|
/* kp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kr */ SUFFIX | NOT_END,
|
|
/* ks */ NOT_BEGIN | END,
|
|
/* kt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ku */ ANY_COMBINATION,
|
|
/* kv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kx */ ILLEGAL_PAIR,
|
|
/* ky */ NOT_BEGIN,
|
|
/* kz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kph */ NOT_BEGIN | PREFIX,
|
|
/* krh */ ILLEGAL_PAIR,
|
|
/* ksh */ NOT_BEGIN,
|
|
/* kth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kwh */ ILLEGAL_PAIR,
|
|
/* kqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* kck */ ILLEGAL_PAIR },
|
|
{/* la */ ANY_COMBINATION,
|
|
/* lb */ NOT_BEGIN | PREFIX,
|
|
/* lc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ld */ NOT_BEGIN | PREFIX,
|
|
/* le */ ANY_COMBINATION,
|
|
/* lf */ NOT_BEGIN | PREFIX,
|
|
/* lg */ NOT_BEGIN | PREFIX,
|
|
/* lh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* li */ ANY_COMBINATION,
|
|
/* lj */ NOT_BEGIN | PREFIX,
|
|
/* lk */ NOT_BEGIN | PREFIX,
|
|
/* ll */ NOT_BEGIN | PREFIX,
|
|
/* lm */ NOT_BEGIN | PREFIX,
|
|
/* ln */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* lo */ ANY_COMBINATION,
|
|
/* lp */ NOT_BEGIN | PREFIX,
|
|
/* lr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ls */ NOT_BEGIN,
|
|
/* lt */ NOT_BEGIN | PREFIX,
|
|
/* lu */ ANY_COMBINATION,
|
|
/* lv */ NOT_BEGIN | PREFIX,
|
|
/* lw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* lx */ ILLEGAL_PAIR,
|
|
/* ly */ ANY_COMBINATION,
|
|
/* lz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* lch */ NOT_BEGIN | PREFIX,
|
|
/* lgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* lph */ NOT_BEGIN | PREFIX,
|
|
/* lrh */ ILLEGAL_PAIR,
|
|
/* lsh */ NOT_BEGIN | PREFIX,
|
|
/* lth */ NOT_BEGIN | PREFIX,
|
|
/* lwh */ ILLEGAL_PAIR,
|
|
/* lqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* lck */ ILLEGAL_PAIR },
|
|
{/* ma */ ANY_COMBINATION,
|
|
/* mb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* md */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* me */ ANY_COMBINATION,
|
|
/* mf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mi */ ANY_COMBINATION,
|
|
/* mj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ml */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mm */ NOT_BEGIN,
|
|
/* mn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mo */ ANY_COMBINATION,
|
|
/* mp */ NOT_BEGIN,
|
|
/* mr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ms */ NOT_BEGIN,
|
|
/* mt */ NOT_BEGIN,
|
|
/* mu */ ANY_COMBINATION,
|
|
/* mv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mx */ ILLEGAL_PAIR,
|
|
/* my */ ANY_COMBINATION,
|
|
/* mz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mch */ NOT_BEGIN | PREFIX,
|
|
/* mgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mph */ NOT_BEGIN,
|
|
/* mrh */ ILLEGAL_PAIR,
|
|
/* msh */ NOT_BEGIN,
|
|
/* mth */ NOT_BEGIN,
|
|
/* mwh */ ILLEGAL_PAIR,
|
|
/* mqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* mck */ ILLEGAL_PAIR },
|
|
{/* na */ ANY_COMBINATION,
|
|
/* nb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nd */ NOT_BEGIN,
|
|
/* ne */ ANY_COMBINATION,
|
|
/* nf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ng */ NOT_BEGIN | PREFIX,
|
|
/* nh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ni */ ANY_COMBINATION,
|
|
/* nj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nk */ NOT_BEGIN | PREFIX,
|
|
/* nl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nn */ NOT_BEGIN,
|
|
/* no */ ANY_COMBINATION,
|
|
/* np */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ns */ NOT_BEGIN,
|
|
/* nt */ NOT_BEGIN,
|
|
/* nu */ ANY_COMBINATION,
|
|
/* nv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nx */ ILLEGAL_PAIR,
|
|
/* ny */ NOT_BEGIN,
|
|
/* nz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nch */ NOT_BEGIN | PREFIX,
|
|
/* ngh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nph */ NOT_BEGIN | PREFIX,
|
|
/* nrh */ ILLEGAL_PAIR,
|
|
/* nsh */ NOT_BEGIN,
|
|
/* nth */ NOT_BEGIN,
|
|
/* nwh */ ILLEGAL_PAIR,
|
|
/* nqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* nck */ NOT_BEGIN | PREFIX },
|
|
{/* oa */ ANY_COMBINATION,
|
|
/* ob */ ANY_COMBINATION,
|
|
/* oc */ ANY_COMBINATION,
|
|
/* od */ ANY_COMBINATION,
|
|
/* oe */ ILLEGAL_PAIR,
|
|
/* of */ ANY_COMBINATION,
|
|
/* og */ ANY_COMBINATION,
|
|
/* oh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* oi */ ANY_COMBINATION,
|
|
/* oj */ ANY_COMBINATION,
|
|
/* ok */ ANY_COMBINATION,
|
|
/* ol */ ANY_COMBINATION,
|
|
/* om */ ANY_COMBINATION,
|
|
/* on */ ANY_COMBINATION,
|
|
/* oo */ ANY_COMBINATION,
|
|
/* op */ ANY_COMBINATION,
|
|
/* or */ ANY_COMBINATION,
|
|
/* os */ ANY_COMBINATION,
|
|
/* ot */ ANY_COMBINATION,
|
|
/* ou */ ANY_COMBINATION,
|
|
/* ov */ ANY_COMBINATION,
|
|
/* ow */ ANY_COMBINATION,
|
|
/* ox */ ANY_COMBINATION,
|
|
/* oy */ ANY_COMBINATION,
|
|
/* oz */ ANY_COMBINATION,
|
|
/* och */ ANY_COMBINATION,
|
|
/* ogh */ NOT_BEGIN,
|
|
/* oph */ ANY_COMBINATION,
|
|
/* orh */ ILLEGAL_PAIR,
|
|
/* osh */ ANY_COMBINATION,
|
|
/* oth */ ANY_COMBINATION,
|
|
/* owh */ ILLEGAL_PAIR,
|
|
/* oqu */ BREAK | NOT_END,
|
|
/* ock */ ANY_COMBINATION },
|
|
{/* pa */ ANY_COMBINATION,
|
|
/* pb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pe */ ANY_COMBINATION,
|
|
/* pf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pi */ ANY_COMBINATION,
|
|
/* pj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pl */ SUFFIX | NOT_END,
|
|
/* pm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* po */ ANY_COMBINATION,
|
|
/* pp */ NOT_BEGIN | PREFIX,
|
|
/* pr */ NOT_END,
|
|
/* ps */ NOT_BEGIN | END,
|
|
/* pt */ NOT_BEGIN | END,
|
|
/* pu */ NOT_BEGIN | END,
|
|
/* pv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* px */ ILLEGAL_PAIR,
|
|
/* py */ ANY_COMBINATION,
|
|
/* pz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* prh */ ILLEGAL_PAIR,
|
|
/* psh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pwh */ ILLEGAL_PAIR,
|
|
/* pqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pck */ ILLEGAL_PAIR },
|
|
{/* ra */ ANY_COMBINATION,
|
|
/* rb */ NOT_BEGIN | PREFIX,
|
|
/* rc */ NOT_BEGIN | PREFIX,
|
|
/* rd */ NOT_BEGIN | PREFIX,
|
|
/* re */ ANY_COMBINATION,
|
|
/* rf */ NOT_BEGIN | PREFIX,
|
|
/* rg */ NOT_BEGIN | PREFIX,
|
|
/* rh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ri */ ANY_COMBINATION,
|
|
/* rj */ NOT_BEGIN | PREFIX,
|
|
/* rk */ NOT_BEGIN | PREFIX,
|
|
/* rl */ NOT_BEGIN | PREFIX,
|
|
/* rm */ NOT_BEGIN | PREFIX,
|
|
/* rn */ NOT_BEGIN | PREFIX,
|
|
/* ro */ ANY_COMBINATION,
|
|
/* rp */ NOT_BEGIN | PREFIX,
|
|
/* rr */ NOT_BEGIN | PREFIX,
|
|
/* rs */ NOT_BEGIN | PREFIX,
|
|
/* rt */ NOT_BEGIN | PREFIX,
|
|
/* ru */ ANY_COMBINATION,
|
|
/* rv */ NOT_BEGIN | PREFIX,
|
|
/* rw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* rx */ ILLEGAL_PAIR,
|
|
/* ry */ ANY_COMBINATION,
|
|
/* rz */ NOT_BEGIN | PREFIX,
|
|
/* rch */ NOT_BEGIN | PREFIX,
|
|
/* rgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* rph */ NOT_BEGIN | PREFIX,
|
|
/* rrh */ ILLEGAL_PAIR,
|
|
/* rsh */ NOT_BEGIN | PREFIX,
|
|
/* rth */ NOT_BEGIN | PREFIX,
|
|
/* rwh */ ILLEGAL_PAIR,
|
|
/* rqu */ NOT_BEGIN | PREFIX | NOT_END,
|
|
/* rck */ NOT_BEGIN | PREFIX },
|
|
{/* sa */ ANY_COMBINATION,
|
|
/* sb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sc */ NOT_END,
|
|
/* sd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* se */ ANY_COMBINATION,
|
|
/* sf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* si */ ANY_COMBINATION,
|
|
/* sj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sk */ ANY_COMBINATION,
|
|
/* sl */ BEGIN | SUFFIX | NOT_END,
|
|
/* sm */ SUFFIX | NOT_END,
|
|
/* sn */ PREFIX | SUFFIX | NOT_END,
|
|
/* so */ ANY_COMBINATION,
|
|
/* sp */ ANY_COMBINATION,
|
|
/* sr */ NOT_BEGIN | NOT_END,
|
|
/* ss */ NOT_BEGIN | PREFIX,
|
|
/* st */ ANY_COMBINATION,
|
|
/* su */ ANY_COMBINATION,
|
|
/* sv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sw */ BEGIN | SUFFIX | NOT_END,
|
|
/* sx */ ILLEGAL_PAIR,
|
|
/* sy */ ANY_COMBINATION,
|
|
/* sz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sch */ BEGIN | SUFFIX | NOT_END,
|
|
/* sgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* srh */ ILLEGAL_PAIR,
|
|
/* ssh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* swh */ ILLEGAL_PAIR,
|
|
/* squ */ SUFFIX | NOT_END,
|
|
/* sck */ NOT_BEGIN },
|
|
{/* ta */ ANY_COMBINATION,
|
|
/* tb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* td */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* te */ ANY_COMBINATION,
|
|
/* tf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* th */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ti */ ANY_COMBINATION,
|
|
/* tj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* to */ ANY_COMBINATION,
|
|
/* tp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tr */ NOT_END,
|
|
/* ts */ NOT_BEGIN | END,
|
|
/* tt */ NOT_BEGIN | PREFIX,
|
|
/* tu */ ANY_COMBINATION,
|
|
/* tv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tw */ BEGIN | SUFFIX | NOT_END,
|
|
/* tx */ ILLEGAL_PAIR,
|
|
/* ty */ ANY_COMBINATION,
|
|
/* tz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tch */ NOT_BEGIN,
|
|
/* tgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tph */ NOT_BEGIN | END,
|
|
/* trh */ ILLEGAL_PAIR,
|
|
/* tsh */ NOT_BEGIN | END,
|
|
/* tth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* twh */ ILLEGAL_PAIR,
|
|
/* tqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tck */ ILLEGAL_PAIR },
|
|
{/* ua */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ub */ ANY_COMBINATION,
|
|
/* uc */ ANY_COMBINATION,
|
|
/* ud */ ANY_COMBINATION,
|
|
/* ue */ NOT_BEGIN,
|
|
/* uf */ ANY_COMBINATION,
|
|
/* ug */ ANY_COMBINATION,
|
|
/* uh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ui */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* uj */ ANY_COMBINATION,
|
|
/* uk */ ANY_COMBINATION,
|
|
/* ul */ ANY_COMBINATION,
|
|
/* um */ ANY_COMBINATION,
|
|
/* un */ ANY_COMBINATION,
|
|
/* uo */ NOT_BEGIN | BREAK,
|
|
/* up */ ANY_COMBINATION,
|
|
/* ur */ ANY_COMBINATION,
|
|
/* us */ ANY_COMBINATION,
|
|
/* ut */ ANY_COMBINATION,
|
|
/* uu */ ILLEGAL_PAIR,
|
|
/* uv */ ANY_COMBINATION,
|
|
/* uw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ux */ ANY_COMBINATION,
|
|
/* uy */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* uz */ ANY_COMBINATION,
|
|
/* uch */ ANY_COMBINATION,
|
|
/* ugh */ NOT_BEGIN | PREFIX,
|
|
/* uph */ ANY_COMBINATION,
|
|
/* urh */ ILLEGAL_PAIR,
|
|
/* ush */ ANY_COMBINATION,
|
|
/* uth */ ANY_COMBINATION,
|
|
/* uwh */ ILLEGAL_PAIR,
|
|
/* uqu */ BREAK | NOT_END,
|
|
/* uck */ ANY_COMBINATION },
|
|
{/* va */ ANY_COMBINATION,
|
|
/* vb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ve */ ANY_COMBINATION,
|
|
/* vf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vi */ ANY_COMBINATION,
|
|
/* vj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vo */ ANY_COMBINATION,
|
|
/* vp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vs */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vu */ ANY_COMBINATION,
|
|
/* vv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vx */ ILLEGAL_PAIR,
|
|
/* vy */ NOT_BEGIN,
|
|
/* vz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vrh */ ILLEGAL_PAIR,
|
|
/* vsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vwh */ ILLEGAL_PAIR,
|
|
/* vqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* vck */ ILLEGAL_PAIR },
|
|
{/* wa */ ANY_COMBINATION,
|
|
/* wb */ NOT_BEGIN | PREFIX,
|
|
/* wc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* wd */ NOT_BEGIN | PREFIX | END,
|
|
/* we */ ANY_COMBINATION,
|
|
/* wf */ NOT_BEGIN | PREFIX,
|
|
/* wg */ NOT_BEGIN | PREFIX | END,
|
|
/* wh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* wi */ ANY_COMBINATION,
|
|
/* wj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* wk */ NOT_BEGIN | PREFIX,
|
|
/* wl */ NOT_BEGIN | PREFIX | SUFFIX,
|
|
/* wm */ NOT_BEGIN | PREFIX,
|
|
/* wn */ NOT_BEGIN | PREFIX,
|
|
/* wo */ ANY_COMBINATION,
|
|
/* wp */ NOT_BEGIN | PREFIX,
|
|
/* wr */ BEGIN | SUFFIX | NOT_END,
|
|
/* ws */ NOT_BEGIN | PREFIX,
|
|
/* wt */ NOT_BEGIN | PREFIX,
|
|
/* wu */ ANY_COMBINATION,
|
|
/* wv */ NOT_BEGIN | PREFIX,
|
|
/* ww */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* wx */ NOT_BEGIN | PREFIX,
|
|
/* wy */ ANY_COMBINATION,
|
|
/* wz */ NOT_BEGIN | PREFIX,
|
|
/* wch */ NOT_BEGIN,
|
|
/* wgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* wph */ NOT_BEGIN,
|
|
/* wrh */ ILLEGAL_PAIR,
|
|
/* wsh */ NOT_BEGIN,
|
|
/* wth */ NOT_BEGIN,
|
|
/* wwh */ ILLEGAL_PAIR,
|
|
/* wqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* wck */ NOT_BEGIN },
|
|
{/* xa */ NOT_BEGIN,
|
|
/* xb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xe */ NOT_BEGIN,
|
|
/* xf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xi */ NOT_BEGIN,
|
|
/* xj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xo */ NOT_BEGIN,
|
|
/* xp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xs */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xu */ NOT_BEGIN,
|
|
/* xv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xx */ ILLEGAL_PAIR,
|
|
/* xy */ NOT_BEGIN,
|
|
/* xz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xrh */ ILLEGAL_PAIR,
|
|
/* xsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xwh */ ILLEGAL_PAIR,
|
|
/* xqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* xck */ ILLEGAL_PAIR },
|
|
{/* ya */ ANY_COMBINATION,
|
|
/* yb */ NOT_BEGIN,
|
|
/* yc */ NOT_BEGIN | NOT_END,
|
|
/* yd */ NOT_BEGIN,
|
|
/* ye */ ANY_COMBINATION,
|
|
/* yf */ NOT_BEGIN | NOT_END,
|
|
/* yg */ NOT_BEGIN,
|
|
/* yh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* yi */ BEGIN | NOT_END,
|
|
/* yj */ NOT_BEGIN | NOT_END,
|
|
/* yk */ NOT_BEGIN,
|
|
/* yl */ NOT_BEGIN | NOT_END,
|
|
/* ym */ NOT_BEGIN,
|
|
/* yn */ NOT_BEGIN,
|
|
/* yo */ ANY_COMBINATION,
|
|
/* yp */ NOT_BEGIN,
|
|
/* yr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ys */ NOT_BEGIN,
|
|
/* yt */ NOT_BEGIN,
|
|
/* yu */ ANY_COMBINATION,
|
|
/* yv */ NOT_BEGIN | NOT_END,
|
|
/* yw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* yx */ NOT_BEGIN,
|
|
/* yy */ ILLEGAL_PAIR,
|
|
/* yz */ NOT_BEGIN,
|
|
/* ych */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ygh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* yph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* yrh */ ILLEGAL_PAIR,
|
|
/* ysh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* yth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ywh */ ILLEGAL_PAIR,
|
|
/* yqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* yck */ ILLEGAL_PAIR },
|
|
{/* za */ ANY_COMBINATION,
|
|
/* zb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ze */ ANY_COMBINATION,
|
|
/* zf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zi */ ANY_COMBINATION,
|
|
/* zj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zo */ ANY_COMBINATION,
|
|
/* zp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zr */ NOT_BEGIN | NOT_END,
|
|
/* zs */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zt */ NOT_BEGIN,
|
|
/* zu */ ANY_COMBINATION,
|
|
/* zv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zw */ SUFFIX | NOT_END,
|
|
/* zx */ ILLEGAL_PAIR,
|
|
/* zy */ ANY_COMBINATION,
|
|
/* zz */ NOT_BEGIN,
|
|
/* zch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zrh */ ILLEGAL_PAIR,
|
|
/* zsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zwh */ ILLEGAL_PAIR,
|
|
/* zqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* zck */ ILLEGAL_PAIR },
|
|
{/* cha */ ANY_COMBINATION,
|
|
/* chb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* che */ ANY_COMBINATION,
|
|
/* chf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chi */ ANY_COMBINATION,
|
|
/* chj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cho */ ANY_COMBINATION,
|
|
/* chp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chr */ NOT_END,
|
|
/* chs */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cht */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chu */ ANY_COMBINATION,
|
|
/* chv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chw */ NOT_BEGIN | NOT_END,
|
|
/* chx */ ILLEGAL_PAIR,
|
|
/* chy */ ANY_COMBINATION,
|
|
/* chz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chch */ ILLEGAL_PAIR,
|
|
/* chgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chrh */ ILLEGAL_PAIR,
|
|
/* chsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chwh */ ILLEGAL_PAIR,
|
|
/* chqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* chck */ ILLEGAL_PAIR },
|
|
{/* gha */ ANY_COMBINATION,
|
|
/* ghb */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghc */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghd */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghe */ ANY_COMBINATION,
|
|
/* ghf */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghg */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghh */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghi */ BEGIN | NOT_END,
|
|
/* ghj */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghk */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghl */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghm */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghn */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* gho */ BEGIN | NOT_END,
|
|
/* ghp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ghr */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghs */ NOT_BEGIN | PREFIX,
|
|
/* ght */ NOT_BEGIN | PREFIX,
|
|
/* ghu */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghv */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghw */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghx */ ILLEGAL_PAIR,
|
|
/* ghy */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghz */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghch */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghgh */ ILLEGAL_PAIR,
|
|
/* ghph */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghrh */ ILLEGAL_PAIR,
|
|
/* ghsh */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghth */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghwh */ ILLEGAL_PAIR,
|
|
/* ghqu */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
|
|
/* ghck */ ILLEGAL_PAIR },
|
|
{/* pha */ ANY_COMBINATION,
|
|
/* phb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phe */ ANY_COMBINATION,
|
|
/* phf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phi */ ANY_COMBINATION,
|
|
/* phj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phl */ BEGIN | SUFFIX | NOT_END,
|
|
/* phm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* pho */ ANY_COMBINATION,
|
|
/* php */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phr */ NOT_END,
|
|
/* phs */ NOT_BEGIN,
|
|
/* pht */ NOT_BEGIN,
|
|
/* phu */ ANY_COMBINATION,
|
|
/* phv */ NOT_BEGIN | NOT_END,
|
|
/* phw */ NOT_BEGIN | NOT_END,
|
|
/* phx */ ILLEGAL_PAIR,
|
|
/* phy */ NOT_BEGIN,
|
|
/* phz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phph */ ILLEGAL_PAIR,
|
|
/* phrh */ ILLEGAL_PAIR,
|
|
/* phsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phwh */ ILLEGAL_PAIR,
|
|
/* phqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* phck */ ILLEGAL_PAIR },
|
|
{/* rha */ BEGIN | NOT_END,
|
|
/* rhb */ ILLEGAL_PAIR,
|
|
/* rhc */ ILLEGAL_PAIR,
|
|
/* rhd */ ILLEGAL_PAIR,
|
|
/* rhe */ BEGIN | NOT_END,
|
|
/* rhf */ ILLEGAL_PAIR,
|
|
/* rhg */ ILLEGAL_PAIR,
|
|
/* rhh */ ILLEGAL_PAIR,
|
|
/* rhi */ BEGIN | NOT_END,
|
|
/* rhj */ ILLEGAL_PAIR,
|
|
/* rhk */ ILLEGAL_PAIR,
|
|
/* rhl */ ILLEGAL_PAIR,
|
|
/* rhm */ ILLEGAL_PAIR,
|
|
/* rhn */ ILLEGAL_PAIR,
|
|
/* rho */ BEGIN | NOT_END,
|
|
/* rhp */ ILLEGAL_PAIR,
|
|
/* rhr */ ILLEGAL_PAIR,
|
|
/* rhs */ ILLEGAL_PAIR,
|
|
/* rht */ ILLEGAL_PAIR,
|
|
/* rhu */ BEGIN | NOT_END,
|
|
/* rhv */ ILLEGAL_PAIR,
|
|
/* rhw */ ILLEGAL_PAIR,
|
|
/* rhx */ ILLEGAL_PAIR,
|
|
/* rhy */ BEGIN | NOT_END,
|
|
/* rhz */ ILLEGAL_PAIR,
|
|
/* rhch */ ILLEGAL_PAIR,
|
|
/* rhgh */ ILLEGAL_PAIR,
|
|
/* rhph */ ILLEGAL_PAIR,
|
|
/* rhrh */ ILLEGAL_PAIR,
|
|
/* rhsh */ ILLEGAL_PAIR,
|
|
/* rhth */ ILLEGAL_PAIR,
|
|
/* rhwh */ ILLEGAL_PAIR,
|
|
/* rhqu */ ILLEGAL_PAIR,
|
|
/* rhck */ ILLEGAL_PAIR },
|
|
{/* sha */ ANY_COMBINATION,
|
|
/* shb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* she */ ANY_COMBINATION,
|
|
/* shf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shh */ ILLEGAL_PAIR,
|
|
/* shi */ ANY_COMBINATION,
|
|
/* shj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shk */ NOT_BEGIN,
|
|
/* shl */ BEGIN | SUFFIX | NOT_END,
|
|
/* shm */ BEGIN | SUFFIX | NOT_END,
|
|
/* shn */ BEGIN | SUFFIX | NOT_END,
|
|
/* sho */ ANY_COMBINATION,
|
|
/* shp */ NOT_BEGIN,
|
|
/* shr */ BEGIN | SUFFIX | NOT_END,
|
|
/* shs */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* sht */ SUFFIX,
|
|
/* shu */ ANY_COMBINATION,
|
|
/* shv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shw */ SUFFIX | NOT_END,
|
|
/* shx */ ILLEGAL_PAIR,
|
|
/* shy */ ANY_COMBINATION,
|
|
/* shz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shrh */ ILLEGAL_PAIR,
|
|
/* shsh */ ILLEGAL_PAIR,
|
|
/* shth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shwh */ ILLEGAL_PAIR,
|
|
/* shqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* shck */ ILLEGAL_PAIR },
|
|
{/* tha */ ANY_COMBINATION,
|
|
/* thb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* the */ ANY_COMBINATION,
|
|
/* thf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thi */ ANY_COMBINATION,
|
|
/* thj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* tho */ ANY_COMBINATION,
|
|
/* thp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thr */ NOT_END,
|
|
/* ths */ NOT_BEGIN | END,
|
|
/* tht */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thu */ ANY_COMBINATION,
|
|
/* thv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thw */ SUFFIX | NOT_END,
|
|
/* thx */ ILLEGAL_PAIR,
|
|
/* thy */ ANY_COMBINATION,
|
|
/* thz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thrh */ ILLEGAL_PAIR,
|
|
/* thsh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thth */ ILLEGAL_PAIR,
|
|
/* thwh */ ILLEGAL_PAIR,
|
|
/* thqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* thck */ ILLEGAL_PAIR },
|
|
{/* wha */ BEGIN | NOT_END,
|
|
/* whb */ ILLEGAL_PAIR,
|
|
/* whc */ ILLEGAL_PAIR,
|
|
/* whd */ ILLEGAL_PAIR,
|
|
/* whe */ BEGIN | NOT_END,
|
|
/* whf */ ILLEGAL_PAIR,
|
|
/* whg */ ILLEGAL_PAIR,
|
|
/* whh */ ILLEGAL_PAIR,
|
|
/* whi */ BEGIN | NOT_END,
|
|
/* whj */ ILLEGAL_PAIR,
|
|
/* whk */ ILLEGAL_PAIR,
|
|
/* whl */ ILLEGAL_PAIR,
|
|
/* whm */ ILLEGAL_PAIR,
|
|
/* whn */ ILLEGAL_PAIR,
|
|
/* who */ BEGIN | NOT_END,
|
|
/* whp */ ILLEGAL_PAIR,
|
|
/* whr */ ILLEGAL_PAIR,
|
|
/* whs */ ILLEGAL_PAIR,
|
|
/* wht */ ILLEGAL_PAIR,
|
|
/* whu */ ILLEGAL_PAIR,
|
|
/* whv */ ILLEGAL_PAIR,
|
|
/* whw */ ILLEGAL_PAIR,
|
|
/* whx */ ILLEGAL_PAIR,
|
|
/* why */ BEGIN | NOT_END,
|
|
/* whz */ ILLEGAL_PAIR,
|
|
/* whch */ ILLEGAL_PAIR,
|
|
/* whgh */ ILLEGAL_PAIR,
|
|
/* whph */ ILLEGAL_PAIR,
|
|
/* whrh */ ILLEGAL_PAIR,
|
|
/* whsh */ ILLEGAL_PAIR,
|
|
/* whth */ ILLEGAL_PAIR,
|
|
/* whwh */ ILLEGAL_PAIR,
|
|
/* whqu */ ILLEGAL_PAIR,
|
|
/* whck */ ILLEGAL_PAIR },
|
|
{/* qua */ ANY_COMBINATION,
|
|
/* qub */ ILLEGAL_PAIR,
|
|
/* quc */ ILLEGAL_PAIR,
|
|
/* qud */ ILLEGAL_PAIR,
|
|
/* que */ ANY_COMBINATION,
|
|
/* quf */ ILLEGAL_PAIR,
|
|
/* qug */ ILLEGAL_PAIR,
|
|
/* quh */ ILLEGAL_PAIR,
|
|
/* qui */ ANY_COMBINATION,
|
|
/* quj */ ILLEGAL_PAIR,
|
|
/* quk */ ILLEGAL_PAIR,
|
|
/* qul */ ILLEGAL_PAIR,
|
|
/* qum */ ILLEGAL_PAIR,
|
|
/* qun */ ILLEGAL_PAIR,
|
|
/* quo */ ANY_COMBINATION,
|
|
/* qup */ ILLEGAL_PAIR,
|
|
/* qur */ ILLEGAL_PAIR,
|
|
/* qus */ ILLEGAL_PAIR,
|
|
/* qut */ ILLEGAL_PAIR,
|
|
/* quu */ ILLEGAL_PAIR,
|
|
/* quv */ ILLEGAL_PAIR,
|
|
/* quw */ ILLEGAL_PAIR,
|
|
/* qux */ ILLEGAL_PAIR,
|
|
/* quy */ ILLEGAL_PAIR,
|
|
/* quz */ ILLEGAL_PAIR,
|
|
/* quch */ ILLEGAL_PAIR,
|
|
/* qugh */ ILLEGAL_PAIR,
|
|
/* quph */ ILLEGAL_PAIR,
|
|
/* qurh */ ILLEGAL_PAIR,
|
|
/* qush */ ILLEGAL_PAIR,
|
|
/* quth */ ILLEGAL_PAIR,
|
|
/* quwh */ ILLEGAL_PAIR,
|
|
/* ququ */ ILLEGAL_PAIR,
|
|
/* quck */ ILLEGAL_PAIR },
|
|
{/* cka */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckb */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckc */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckd */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cke */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckf */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckg */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cki */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckj */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckk */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckl */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckm */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckn */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cko */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckp */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckr */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cks */ NOT_BEGIN,
|
|
/* ckt */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* cku */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckv */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckw */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckx */ ILLEGAL_PAIR,
|
|
/* cky */ NOT_BEGIN,
|
|
/* ckz */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckch */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckgh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckph */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckrh */ ILLEGAL_PAIR,
|
|
/* cksh */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckth */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckwh */ ILLEGAL_PAIR,
|
|
/* ckqu */ NOT_BEGIN | BREAK | NOT_END,
|
|
/* ckck */ ILLEGAL_PAIR}
|
|
};
|
|
|
|
/*
|
|
** gen_pron_pass will generate a Random word and place it in the
|
|
** buffer word. Also, the hyphenated word will be placed into
|
|
** the buffer hyphenated_word. Both word and hyphenated_word must
|
|
** be pre-allocated. The words generated will have sizes between
|
|
** minlen and maxlen. If restrict is TRUE, words will not be generated that
|
|
** appear as login names or as entries in the on-line dictionary.
|
|
** This algorithm was initially worded out by Morrie Gasser in 1975.
|
|
** Any changes here are minimal so that as many word combinations
|
|
** can be produced as possible (and thus keep the words Random).
|
|
** The seed is used on first use of the routine.
|
|
** The length of the unhyphenated word is returned, or -1 if there
|
|
** were an error (length settings are wrong or dictionary checking
|
|
** could not be done.
|
|
*/
|
|
int
|
|
gen_pron_pass (char *word, char *hyphenated_word, USHORT minlen,
|
|
USHORT maxlen, unsigned int pass_mode)
|
|
{
|
|
|
|
int pwlen;
|
|
|
|
/*
|
|
* Check for minlen>maxlen. This is an error.
|
|
* and a length of 0.
|
|
*/
|
|
if (minlen > maxlen || minlen > APG_MAX_PASSWORD_LENGTH ||
|
|
maxlen > APG_MAX_PASSWORD_LENGTH)
|
|
return (-1);
|
|
/*
|
|
* Check for zero length words. This is technically not an error,
|
|
* so we take the short cut and return a null word and a length of 0.
|
|
*/
|
|
if (maxlen == 0)
|
|
{
|
|
word[0] = '\0';
|
|
hyphenated_word[0] = '\0';
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Find password.
|
|
*/
|
|
pwlen = gen_word (word, hyphenated_word, get_random (minlen, maxlen), pass_mode);
|
|
return (pwlen);
|
|
}
|
|
|
|
|
|
/*
|
|
* This is the routine that returns a Random word -- as
|
|
* yet unchecked against the passwd file or the dictionary.
|
|
* It collects Random syllables until a predetermined
|
|
* word length is found. If a retry threshold is reached,
|
|
* another word is tried. Given that the Random number
|
|
* generator is uniformly distributed, eventually a word
|
|
* will be found if the retry limit is adequately large enough.
|
|
*/
|
|
int
|
|
gen_word (char *word, char *hyphenated_word, USHORT pwlen, unsigned int pass_mode)
|
|
{
|
|
USHORT word_length;
|
|
USHORT syllable_length;
|
|
char *new_syllable;
|
|
char *syllable_for_hyph;
|
|
USHORT *syllable_units;
|
|
USHORT word_size;
|
|
USHORT word_place;
|
|
USHORT *word_units;
|
|
USHORT syllable_size;
|
|
UINT tries;
|
|
int ch_flag = FALSE;
|
|
int dsd = 0;
|
|
|
|
/*
|
|
* Keep count of retries.
|
|
*/
|
|
tries = 0;
|
|
|
|
/*
|
|
* The length of the word in characters.
|
|
*/
|
|
word_length = 0;
|
|
|
|
/*
|
|
* The length of the word in character units (each of which is one or
|
|
* two characters long.
|
|
*/
|
|
word_size = 0;
|
|
|
|
/*
|
|
* Initialize the array storing the word units. Since we know the
|
|
* length of the word, we only need one of that length. This method is
|
|
* preferable to a static array, since it allows us flexibility in
|
|
* choosing arbitrarily long word lengths. Since a word can contain one
|
|
* syllable, we should make syllable_units, the array holding the
|
|
* analogous units for an individual syllable, the same length. No
|
|
* explicit rule limits the length of syllables, but digram rules and
|
|
* heuristics do so indirectly.
|
|
*/
|
|
if ( (word_units = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL ||
|
|
(syllable_units = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL ||
|
|
(new_syllable = (char *) calloc (sizeof (USHORT), pwlen+1)) ==NULL ||
|
|
(syllable_for_hyph = (char *) calloc (sizeof(char), 20))==NULL)
|
|
return(-1);
|
|
|
|
/*
|
|
* Find syllables until the entire word is constructed.
|
|
*/
|
|
while (word_length < pwlen)
|
|
{
|
|
/*
|
|
* Get the syllable and find its length.
|
|
*/
|
|
(void) gen_syllable (new_syllable, pwlen - word_length, syllable_units, &syllable_size);
|
|
syllable_length = strlen (new_syllable);
|
|
|
|
/*
|
|
* Append the syllable units to the word units.
|
|
*/
|
|
for (word_place = 0; word_place <= syllable_size; word_place++)
|
|
word_units[word_size + word_place] = syllable_units[word_place];
|
|
word_size += syllable_size + 1;
|
|
|
|
/*
|
|
* If the word has been improperly formed, throw out
|
|
* the syllable. The checks performed here are those
|
|
* that must be formed on a word basis. The other
|
|
* tests are performed entirely within the syllable.
|
|
* Otherwise, append the syllable to the word and
|
|
* append the syllable to the hyphenated version of
|
|
* the word.
|
|
*/
|
|
if (improper_word (word_units, word_size) ||
|
|
((word_length == 0) && have_initial_y (syllable_units, syllable_size)) ||
|
|
((word_length + syllable_length == pwlen) && have_final_split (syllable_units, syllable_size)))
|
|
word_size -= syllable_size + 1;
|
|
else
|
|
{
|
|
if (word_length == 0)
|
|
{
|
|
/*
|
|
** Modify syllable for numeric or capital symbols required
|
|
** Should be done after word quality check.
|
|
*/
|
|
dsd = randint(2);
|
|
if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && dsd == 0)
|
|
{
|
|
numerize(new_syllable);
|
|
ch_flag = TRUE;
|
|
}
|
|
if ( ((pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1))
|
|
{
|
|
specialize(new_syllable);
|
|
ch_flag = TRUE;
|
|
}
|
|
if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE))
|
|
capitalize(new_syllable);
|
|
ch_flag = FALSE;
|
|
/**/
|
|
(void) strcpy (word, new_syllable);
|
|
if (syllable_length == 1)
|
|
{
|
|
symb2name(new_syllable, syllable_for_hyph);
|
|
(void) strcpy (hyphenated_word, syllable_for_hyph);
|
|
}
|
|
else
|
|
{
|
|
(void) strcpy (hyphenated_word, new_syllable);
|
|
}
|
|
(void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1));
|
|
(void)memset ( (void *)syllable_for_hyph, 0, 20);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
** Modify syllable for numeric or capital symbols required
|
|
** Should be done after word quality check.
|
|
*/
|
|
dsd = randint(2);
|
|
if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && (dsd == 0))
|
|
{
|
|
numerize(new_syllable);
|
|
ch_flag = TRUE;
|
|
}
|
|
if ( ( (pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1))
|
|
{
|
|
specialize(new_syllable);
|
|
ch_flag = TRUE;
|
|
}
|
|
if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE))
|
|
capitalize(new_syllable);
|
|
ch_flag = FALSE;
|
|
/**/
|
|
(void) strcat (word, new_syllable);
|
|
(void) strcat (hyphenated_word, "-");
|
|
if (syllable_length == 1)
|
|
{
|
|
symb2name(new_syllable, syllable_for_hyph);
|
|
(void) strcat (hyphenated_word, syllable_for_hyph);
|
|
}
|
|
else
|
|
{
|
|
(void) strcat (hyphenated_word, new_syllable);
|
|
}
|
|
(void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1));
|
|
(void)memset ( (void *)syllable_for_hyph, 0, 20);
|
|
}
|
|
word_length += syllable_length;
|
|
}
|
|
|
|
/*
|
|
* Keep track of the times we have tried to get
|
|
* syllables. If we have exceeded the threshold,
|
|
* reinitialize the pwlen and word_size variables, clear
|
|
* out the word arrays, and start from scratch.
|
|
*/
|
|
tries++;
|
|
if (tries > MAX_RETRIES)
|
|
{
|
|
word_length = 0;
|
|
word_size = 0;
|
|
tries = 0;
|
|
(void) strcpy (word, "");
|
|
(void) strcpy (hyphenated_word, "");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The units arrays and syllable storage are internal to this
|
|
* routine. Since the caller has no need for them, we
|
|
* release the space.
|
|
*/
|
|
free ((char *) new_syllable);
|
|
free ((char *) syllable_units);
|
|
free ((char *) word_units);
|
|
free ((char *) syllable_for_hyph);
|
|
|
|
return ((int) word_length);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Check that the word does not contain illegal combinations
|
|
* that may span syllables. Specifically, these are:
|
|
* 1. An illegal pair of units between syllables.
|
|
* 2. Three consecutive vowel units.
|
|
* 3. Three consecutive consonant units.
|
|
* The checks are made against units (1 or 2 letters), not against
|
|
* the individual letters, so three consecutive units can have
|
|
* the length of 6 at most.
|
|
*/
|
|
boolean
|
|
improper_word (USHORT *units, USHORT word_size)
|
|
{
|
|
USHORT unit_count;
|
|
boolean failure;
|
|
|
|
failure = FALSE;
|
|
|
|
for (unit_count = 0; !failure && (unit_count < word_size);
|
|
unit_count++)
|
|
{
|
|
/*
|
|
* Check for ILLEGAL_PAIR. This should have been caught
|
|
* for units within a syllable, but in some cases it
|
|
* would have gone unnoticed for units between syllables
|
|
* (e.g., when saved_unit's in gen_syllable() were not
|
|
* used).
|
|
*/
|
|
if ((unit_count != 0) &&
|
|
(digram[units[unit_count - 1]][units[unit_count]] &
|
|
ILLEGAL_PAIR))
|
|
failure = TRUE;
|
|
|
|
/*
|
|
* Check for consecutive vowels or consonants. Because
|
|
* the initial y of a syllable is treated as a consonant
|
|
* rather than as a vowel, we exclude y from the first
|
|
* vowel in the vowel test. The only problem comes when
|
|
* y ends a syllable and two other vowels start the next,
|
|
* like fly-oint. Since such words are still
|
|
* pronounceable, we accept this.
|
|
*/
|
|
if (!failure && (unit_count >= 2))
|
|
{
|
|
/*
|
|
* Vowel check.
|
|
*/
|
|
if ((((rules[units[unit_count - 2]].flags & VOWEL) &&
|
|
!(rules[units[unit_count - 2]].flags &
|
|
ALTERNATE_VOWEL)) &&
|
|
(rules[units[unit_count - 1]].flags & VOWEL) &&
|
|
(rules[units[unit_count]].flags & VOWEL)) ||
|
|
/*
|
|
* Consonant check.
|
|
*/
|
|
(!(rules[units[unit_count - 2]].flags & VOWEL) &&
|
|
!(rules[units[unit_count - 1]].flags & VOWEL) &&
|
|
!(rules[units[unit_count]].flags & VOWEL)))
|
|
failure = TRUE;
|
|
}
|
|
}
|
|
|
|
return (failure);
|
|
}
|
|
|
|
|
|
/*
|
|
* Treating y as a vowel is sometimes a problem. Some words
|
|
* get formed that look irregular. One special group is when
|
|
* y starts a word and is the only vowel in the first syllable.
|
|
* The word ycl is one example. We discard words like these.
|
|
*/
|
|
boolean
|
|
have_initial_y (USHORT *units, USHORT unit_size)
|
|
{
|
|
USHORT unit_count;
|
|
USHORT vowel_count;
|
|
USHORT normal_vowel_count;
|
|
|
|
vowel_count = 0;
|
|
normal_vowel_count = 0;
|
|
|
|
for (unit_count = 0; unit_count <= unit_size; unit_count++)
|
|
/*
|
|
* Count vowels.
|
|
*/
|
|
if (rules[units[unit_count]].flags & VOWEL)
|
|
{
|
|
vowel_count++;
|
|
|
|
/*
|
|
* Count the vowels that are not: 1. y, 2. at the start of
|
|
* the word.
|
|
*/
|
|
if (!(rules[units[unit_count]].flags & ALTERNATE_VOWEL) ||
|
|
(unit_count != 0))
|
|
normal_vowel_count++;
|
|
}
|
|
|
|
return ((vowel_count <= 1) && (normal_vowel_count == 0));
|
|
}
|
|
|
|
|
|
/*
|
|
* Besides the problem with the letter y, there is one with
|
|
* a silent e at the end of words, like face or nice. We
|
|
* allow this silent e, but we do not allow it as the only
|
|
* vowel at the end of the word or syllables like ble will
|
|
* be generated.
|
|
*/
|
|
boolean
|
|
have_final_split (USHORT *units, USHORT unit_size)
|
|
{
|
|
USHORT unit_count;
|
|
USHORT vowel_count;
|
|
|
|
vowel_count = 0;
|
|
|
|
/*
|
|
* Count all the vowels in the word.
|
|
*/
|
|
for (unit_count = 0; unit_count <= unit_size; unit_count++)
|
|
if (rules[units[unit_count]].flags & VOWEL)
|
|
vowel_count++;
|
|
|
|
/*
|
|
* Return TRUE iff the only vowel was e, found at the end if the
|
|
* word.
|
|
*/
|
|
return ((vowel_count == 1) &&
|
|
(rules[units[unit_size]].flags & NO_FINAL_SPLIT));
|
|
}
|
|
|
|
|
|
/*
|
|
* Generate next unit to password, making sure that it follows
|
|
* these rules:
|
|
* 1. Each syllable must contain exactly 1 or 2 consecutive
|
|
* vowels, where y is considered a vowel.
|
|
* 2. Syllable end is determined as follows:
|
|
* a. Vowel is generated and previous unit is a
|
|
* consonant and syllable already has a vowel. In
|
|
* this case, new syllable is started and already
|
|
* contains a vowel.
|
|
* b. A pair determined to be a "break" pair is encountered.
|
|
* In this case new syllable is started with second unit
|
|
* of this pair.
|
|
* c. End of password is encountered.
|
|
* d. "begin" pair is encountered legally. New syllable is
|
|
* started with this pair.
|
|
* e. "end" pair is legally encountered. New syllable has
|
|
* nothing yet.
|
|
* 3. Try generating another unit if:
|
|
* a. third consecutive vowel and not y.
|
|
* b. "break" pair generated but no vowel yet in current
|
|
* or previous 2 units are "not_end".
|
|
* c. "begin" pair generated but no vowel in syllable
|
|
* preceding begin pair, or both previous 2 pairs are
|
|
* designated "not_end".
|
|
* d. "end" pair generated but no vowel in current syllable
|
|
* or in "end" pair.
|
|
* e. "not_begin" pair generated but new syllable must
|
|
* begin (because previous syllable ended as defined in
|
|
* 2 above).
|
|
* f. vowel is generated and 2a is satisfied, but no syllable
|
|
* break is possible in previous 3 pairs.
|
|
* g. Second and third units of syllable must begin, and
|
|
* first unit is "alternate_vowel".
|
|
*/
|
|
char *
|
|
gen_syllable (char *syllable, USHORT pwlen, USHORT *units_in_syllable,
|
|
USHORT *syllable_length)
|
|
{
|
|
USHORT unit = 0;
|
|
SHORT current_unit = 0;
|
|
USHORT vowel_count = 0;
|
|
boolean rule_broken;
|
|
boolean want_vowel;
|
|
boolean want_another_unit;
|
|
UINT tries = 0;
|
|
USHORT last_unit = 0;
|
|
SHORT length_left = 0;
|
|
USHORT hold_saved_unit = 0;
|
|
static USHORT saved_unit;
|
|
static USHORT saved_pair[2];
|
|
|
|
/*
|
|
* This is needed if the saved_unit is tries and the syllable then
|
|
* discarded because of the retry limit. Since the saved_unit is OK and
|
|
* fits in nicely with the preceding syllable, we will always use it.
|
|
*/
|
|
hold_saved_unit = saved_unit;
|
|
|
|
/*
|
|
* Loop until valid syllable is found.
|
|
*/
|
|
do
|
|
{
|
|
/*
|
|
* Try for a new syllable. Initialize all pertinent
|
|
* syllable variables.
|
|
*/
|
|
tries = 0;
|
|
saved_unit = hold_saved_unit;
|
|
(void) strcpy (syllable, "");
|
|
vowel_count = 0;
|
|
current_unit = 0;
|
|
length_left = (short int) pwlen;
|
|
want_another_unit = TRUE;
|
|
|
|
/*
|
|
* This loop finds all the units for the syllable.
|
|
*/
|
|
do
|
|
{
|
|
want_vowel = FALSE;
|
|
|
|
/*
|
|
* This loop continues until a valid unit is found for the
|
|
* current position within the syllable.
|
|
*/
|
|
do
|
|
{
|
|
/*
|
|
* If there are saved_unit's from the previous
|
|
* syllable, use them up first.
|
|
*/
|
|
if (saved_unit != 0)
|
|
{
|
|
/*
|
|
* If there were two saved units, the first is
|
|
* guaranteed (by checks performed in the previous
|
|
* syllable) to be valid. We ignore the checks
|
|
* and place it in this syllable manually.
|
|
*/
|
|
if (saved_unit == 2)
|
|
{
|
|
units_in_syllable[0] = saved_pair[1];
|
|
if (rules[saved_pair[1]].flags & VOWEL)
|
|
vowel_count++;
|
|
current_unit++;
|
|
(void) strcpy (syllable, rules[saved_pair[1]].unit_code);
|
|
length_left -= strlen (syllable);
|
|
}
|
|
|
|
/*
|
|
* The unit becomes the last unit checked in the
|
|
* previous syllable.
|
|
*/
|
|
unit = saved_pair[0];
|
|
|
|
/*
|
|
* The saved units have been used. Do not try to
|
|
* reuse them in this syllable (unless this particular
|
|
* syllable is rejected at which point we start to rebuild
|
|
* it with these same saved units.
|
|
*/
|
|
saved_unit = 0;
|
|
}
|
|
else
|
|
/*
|
|
* If we don't have to scoff the saved units,
|
|
* we generate a Random one. If we know it has
|
|
* to be a vowel, we get one rather than looping
|
|
* through until one shows up.
|
|
*/
|
|
if (want_vowel)
|
|
unit = random_unit (VOWEL);
|
|
else
|
|
unit = random_unit (NO_SPECIAL_RULE);
|
|
length_left -= (short int) strlen (rules[unit].unit_code);
|
|
|
|
/*
|
|
* Prevent having a word longer than expected.
|
|
*/
|
|
if (length_left < 0)
|
|
rule_broken = TRUE;
|
|
else
|
|
rule_broken = FALSE;
|
|
|
|
/*
|
|
* First unit of syllable. This is special because the
|
|
* digram tests require 2 units and we don't have that yet.
|
|
* Nevertheless, we can perform some checks.
|
|
*/
|
|
if (current_unit == 0)
|
|
{
|
|
/*
|
|
* If the shouldn't begin a syllable, don't
|
|
* use it.
|
|
*/
|
|
if (rules[unit].flags & NOT_BEGIN_SYLLABLE)
|
|
rule_broken = TRUE;
|
|
else
|
|
/*
|
|
* If this is the last unit of a word,
|
|
* we have a one unit syllable. Since each
|
|
* syllable must have a vowel, we make sure
|
|
* the unit is a vowel. Otherwise, we
|
|
* discard it.
|
|
*/
|
|
if (length_left == 0)
|
|
{
|
|
if (rules[unit].flags & VOWEL)
|
|
want_another_unit = FALSE;
|
|
else
|
|
rule_broken = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* There are some digram tests that are
|
|
* universally true. We test them out.
|
|
*/
|
|
|
|
/*
|
|
* Reject ILLEGAL_PAIRS of units.
|
|
*/
|
|
if ((ALLOWED (ILLEGAL_PAIR)) ||
|
|
|
|
/*
|
|
* Reject units that will be split between syllables
|
|
* when the syllable has no vowels in it.
|
|
*/
|
|
(ALLOWED (BREAK) && (vowel_count == 0)) ||
|
|
|
|
/*
|
|
* Reject a unit that will end a syllable when no
|
|
* previous unit was a vowel and neither is this one.
|
|
*/
|
|
(ALLOWED (END) && (vowel_count == 0) &&
|
|
!(rules[unit].flags & VOWEL)))
|
|
rule_broken = TRUE;
|
|
|
|
if (current_unit == 1)
|
|
{
|
|
/*
|
|
* Reject the unit if we are at te starting digram of
|
|
* a syllable and it does not fit.
|
|
*/
|
|
if (ALLOWED (NOT_BEGIN))
|
|
rule_broken = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* We are not at the start of a syllable.
|
|
* Save the previous unit for later tests.
|
|
*/
|
|
last_unit = units_in_syllable[current_unit - 1];
|
|
|
|
/*
|
|
* Do not allow syllables where the first letter is y
|
|
* and the next pair can begin a syllable. This may
|
|
* lead to splits where y is left alone in a syllable.
|
|
* Also, the combination does not sound to good even
|
|
* if not split.
|
|
*/
|
|
if (((current_unit == 2) &&
|
|
(ALLOWED (BEGIN)) &&
|
|
(rules[units_in_syllable[0]].flags &
|
|
ALTERNATE_VOWEL)) ||
|
|
|
|
/*
|
|
* If this is the last unit of a word, we should
|
|
* reject any digram that cannot end a syllable.
|
|
*/
|
|
(ALLOWED (NOT_END) &&
|
|
(length_left == 0)) ||
|
|
|
|
/*
|
|
* Reject the unit if the digram it forms wants
|
|
* to break the syllable, but the resulting
|
|
* digram that would end the syllable is not
|
|
* allowed to end a syllable.
|
|
*/
|
|
(ALLOWED (BREAK) &&
|
|
(digram[units_in_syllable
|
|
[current_unit - 2]]
|
|
[last_unit] &
|
|
NOT_END)) ||
|
|
|
|
/*
|
|
* Reject the unit if the digram it forms
|
|
* expects a vowel preceding it and there is
|
|
* none.
|
|
*/
|
|
(ALLOWED (PREFIX) &&
|
|
!(rules[units_in_syllable
|
|
[current_unit - 2]].flags &
|
|
VOWEL)))
|
|
rule_broken = TRUE;
|
|
|
|
/*
|
|
* The following checks occur when the current unit
|
|
* is a vowel and we are not looking at a word ending
|
|
* with an e.
|
|
*/
|
|
if (!rule_broken &&
|
|
(rules[unit].flags & VOWEL) &&
|
|
((length_left > 0) ||
|
|
!(rules[last_unit].flags &
|
|
NO_FINAL_SPLIT)))
|
|
{
|
|
/*
|
|
* Don't allow 3 consecutive vowels in a
|
|
* syllable. Although some words formed like this
|
|
* are OK, like beau, most are not.
|
|
*/
|
|
if ((vowel_count > 1) &&
|
|
(rules[last_unit].flags & VOWEL))
|
|
rule_broken = TRUE;
|
|
else
|
|
/*
|
|
* Check for the case of
|
|
* vowels-consonants-vowel, which is only
|
|
* legal if the last vowel is an e and we are
|
|
* the end of the word (wich is not
|
|
* happening here due to a previous check.
|
|
*/
|
|
if ((vowel_count != 0) &&
|
|
!(rules[last_unit].flags & VOWEL))
|
|
{
|
|
/*
|
|
* Try to save the vowel for the next
|
|
* syllable, but if the syllable left here
|
|
* is not proper (i.e., the resulting last
|
|
* digram cannot legally end it), just
|
|
* discard it and try for another.
|
|
*/
|
|
if (digram[units_in_syllable
|
|
[current_unit - 2]]
|
|
[last_unit] &
|
|
NOT_END)
|
|
rule_broken = TRUE;
|
|
else
|
|
{
|
|
saved_unit = 1;
|
|
saved_pair[0] = unit;
|
|
want_another_unit = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The unit picked and the digram formed are legal.
|
|
* We now determine if we can end the syllable. It may,
|
|
* in some cases, mean the last unit(s) may be deferred to
|
|
* the next syllable. We also check here to see if the
|
|
* digram formed expects a vowel to follow.
|
|
*/
|
|
if (!rule_broken && want_another_unit)
|
|
{
|
|
/*
|
|
* This word ends in a silent e.
|
|
*/
|
|
/******/ if (((vowel_count != 0) &&
|
|
(rules[unit].flags & NO_FINAL_SPLIT) &&
|
|
(length_left == 0) &&
|
|
!(rules[last_unit].flags & VOWEL)) ||
|
|
|
|
/*
|
|
* This syllable ends either because the digram
|
|
* is an END pair or we would otherwise exceed
|
|
* the length of the word.
|
|
*/
|
|
(ALLOWED (END) || (length_left == 0)))
|
|
{
|
|
want_another_unit = FALSE;
|
|
}
|
|
else
|
|
/*
|
|
* Since we have a vowel in the syllable
|
|
* already, if the digram calls for the end of the
|
|
* syllable, we can legally split it off. We also
|
|
* make sure that we are not at the end of the
|
|
* dangerous because that syllable may not have
|
|
* vowels, or it may not be a legal syllable end,
|
|
* and the retrying mechanism will loop infinitely
|
|
* with the same digram.
|
|
*/
|
|
if ((vowel_count != 0) && (length_left > 0))
|
|
{
|
|
/*
|
|
* If we must begin a syllable, we do so if
|
|
* the only vowel in THIS syllable is not part
|
|
* of the digram we are pushing to the next
|
|
* syllable.
|
|
*/
|
|
if (ALLOWED (BEGIN) &&
|
|
(current_unit > 1) &&
|
|
!((vowel_count == 1) &&
|
|
(rules[last_unit].flags & VOWEL)))
|
|
{
|
|
saved_unit = 2;
|
|
saved_pair[0] = unit;
|
|
saved_pair[1] = last_unit;
|
|
want_another_unit = FALSE;
|
|
}
|
|
else
|
|
if (ALLOWED (BREAK))
|
|
{
|
|
saved_unit = 1;
|
|
saved_pair[0] = unit;
|
|
want_another_unit = FALSE;
|
|
}
|
|
}
|
|
else
|
|
if (ALLOWED (SUFFIX))
|
|
{
|
|
want_vowel = TRUE;
|
|
}
|
|
}
|
|
}
|
|
/********/
|
|
tries++;
|
|
|
|
/*
|
|
* If this unit was illegal, redetermine the amount of
|
|
* letters left to go in the word.
|
|
*/
|
|
if (rule_broken)
|
|
length_left += (short int) strlen (rules[unit].unit_code);
|
|
}
|
|
while (rule_broken && (tries <= MAX_RETRIES));
|
|
|
|
/*
|
|
* The unit fit OK.
|
|
*/
|
|
if (tries <= MAX_RETRIES)
|
|
{
|
|
/*
|
|
* If the unit were a vowel, count it in.
|
|
* However, if the unit were a y and appear
|
|
* at the start of the syllable, treat it
|
|
* like a constant (so that words like year can
|
|
* appear and not conflict with the 3 consecutive
|
|
* vowel rule.
|
|
*/
|
|
if ((rules[unit].flags & VOWEL) &&
|
|
((current_unit > 0) ||
|
|
!(rules[unit].flags & ALTERNATE_VOWEL)))
|
|
vowel_count++;
|
|
|
|
/*
|
|
* If a unit or units were to be saved, we must
|
|
* adjust the syllable formed. Otherwise, we
|
|
* append the current unit to the syllable.
|
|
*/
|
|
switch (saved_unit)
|
|
{
|
|
case 0:
|
|
units_in_syllable[current_unit] = unit;
|
|
(void) strcat (syllable, rules[unit].unit_code);
|
|
break;
|
|
case 1:
|
|
current_unit--;
|
|
break;
|
|
case 2:
|
|
(void) strcpy (&syllable[strlen (syllable) -
|
|
strlen (rules[last_unit].unit_code)],"");
|
|
length_left += (short int) strlen (rules[last_unit].unit_code);
|
|
current_unit -= 2;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
/*
|
|
* Whoops! Too many tries. We set rule_broken so we can
|
|
* loop in the outer loop and try another syllable.
|
|
*/
|
|
rule_broken = TRUE;
|
|
|
|
/*
|
|
* ...and the syllable length grows.
|
|
*/
|
|
*syllable_length = current_unit;
|
|
|
|
current_unit++;
|
|
}
|
|
while ((tries <= MAX_RETRIES) && want_another_unit);
|
|
}
|
|
while (rule_broken ||
|
|
illegal_placement (units_in_syllable, *syllable_length));
|
|
|
|
return (syllable);
|
|
}
|
|
|
|
|
|
/*
|
|
* This routine goes through an individual syllable and checks
|
|
* for illegal combinations of letters that go beyond looking
|
|
* at digrams. We look at things like 3 consecutive vowels or
|
|
* consonants, or syllables with consonants between vowels (unless
|
|
* one of them is the final silent e).
|
|
*/
|
|
boolean
|
|
illegal_placement (USHORT *units, USHORT pwlen)
|
|
{
|
|
USHORT vowel_count;
|
|
USHORT unit_count;
|
|
boolean failure;
|
|
|
|
vowel_count = 0;
|
|
failure = FALSE;
|
|
|
|
for (unit_count = 0; !failure && (unit_count <= pwlen);
|
|
unit_count++)
|
|
{
|
|
if (unit_count >= 1)
|
|
{
|
|
/*
|
|
* Don't allow vowels to be split with consonants in
|
|
* a single syllable. If we find such a combination
|
|
* (except for the silent e) we have to discard the
|
|
* syllable).
|
|
*/
|
|
if ((!(rules[units[unit_count - 1]].flags & VOWEL) &&
|
|
(rules[units[unit_count]].flags & VOWEL) &&
|
|
!((rules[units[unit_count]].flags & NO_FINAL_SPLIT) &&
|
|
(unit_count == pwlen)) && (vowel_count != 0)) ||
|
|
/*
|
|
* Perform these checks when we have at least 3 units.
|
|
*/
|
|
((unit_count >= 2) &&
|
|
|
|
/*
|
|
* Disallow 3 consecutive consonants.
|
|
*/
|
|
((!(rules[units[unit_count - 2]].flags & VOWEL) &&
|
|
!(rules[units[unit_count - 1]].flags &
|
|
VOWEL) &&
|
|
!(rules[units[unit_count]].flags &
|
|
VOWEL)) ||
|
|
|
|
/*
|
|
* Disallow 3 consecutive vowels, where the first is
|
|
* not a y.
|
|
*/
|
|
(((rules[units[unit_count - 2]].flags &
|
|
VOWEL) &&
|
|
!((rules[units[0]].flags &
|
|
ALTERNATE_VOWEL) &&
|
|
(unit_count == 2))) &&
|
|
(rules[units[unit_count - 1]].flags &
|
|
VOWEL) &&
|
|
(rules[units[unit_count]].flags &
|
|
VOWEL)))))
|
|
failure = TRUE;
|
|
}
|
|
|
|
/*
|
|
* Count the vowels in the syllable. As mentioned somewhere
|
|
* above, exclude the initial y of a syllable. Instead,
|
|
* treat it as a consonant.
|
|
*/
|
|
if ((rules[units[unit_count]].flags & VOWEL) &&
|
|
!((rules[units[0]].flags & ALTERNATE_VOWEL) &&
|
|
(unit_count == 0) && (pwlen != 0)))
|
|
vowel_count++;
|
|
}
|
|
|
|
return (failure);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* This is the standard Random unit generating routine for
|
|
* gen_syllable(). It does not reference the digrams, but
|
|
* assumes that it contains 34 units in a particular order.
|
|
* This routine attempts to return unit indexes with a distribution
|
|
* approaching that of the distribution of the 34 units in
|
|
* English. In order to do this, a Random number (supposedly
|
|
* uniformly distributed) is used to do a table lookup into an
|
|
* array containing unit indices. There are 211 entries in
|
|
* the array for the random_unit entry point. The probability
|
|
* of a particular unit being generated is equal to the
|
|
* fraction of those 211 entries that contain that unit index.
|
|
* For example, the letter `a' is unit number 1. Since unit
|
|
* index 1 appears 10 times in the array, the probability of
|
|
* selecting an `a' is 10/211.
|
|
*
|
|
* Changes may be made to the digram table without affect to this
|
|
* procedure providing the letter-to-number correspondence of
|
|
* the units does not change. Likewise, the distribution of the
|
|
* 34 units may be altered (and the array size may be changed)
|
|
* in this procedure without affecting the digram table or any other
|
|
* programs using the Random_word subroutine.
|
|
*/
|
|
static USHORT numbers[] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
7, 7, 7, 7, 7, 7,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
9, 9, 9, 9, 9, 9, 9, 9,
|
|
10, 10, 10, 10, 10, 10, 10, 10,
|
|
11, 11, 11, 11, 11, 11,
|
|
12, 12, 12, 12, 12, 12,
|
|
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
|
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
|
15, 15, 15, 15, 15, 15,
|
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
17, 17, 17, 17, 17, 17, 17, 17,
|
|
18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
|
19, 19, 19, 19, 19, 19,
|
|
20, 20, 20, 20, 20, 20, 20, 20,
|
|
21, 21, 21, 21, 21, 21, 21, 21,
|
|
22,
|
|
23, 23, 23, 23, 23, 23, 23, 23,
|
|
24,
|
|
25,
|
|
26,
|
|
27,
|
|
28,
|
|
29, 29,
|
|
30,
|
|
31,
|
|
32,
|
|
33
|
|
};
|
|
|
|
|
|
/*
|
|
* This structure has a typical English frequency of vowels.
|
|
* The value of an entry is the vowel position (a=0, e=4, i=8,
|
|
* o=14, u=19, y=23) in the rules array. The number of times
|
|
* the value appears is the frequency. Thus, the letter "a"
|
|
* is assumed to appear 2/12 = 1/6 of the time. This array
|
|
* may be altered if better data is obtained. The routines that
|
|
* use vowel_numbers will adjust to the size difference
|
|
automatically.
|
|
*/
|
|
static USHORT vowel_numbers[] =
|
|
{
|
|
0, 0, 4, 4, 4, 8, 8, 14, 14, 19, 19, 23
|
|
};
|
|
|
|
|
|
/*
|
|
* Select a unit (a letter or a consonant group). If a vowel is
|
|
* expected, use the vowel_numbers array rather than looping through
|
|
* the numbers array until a vowel is found.
|
|
*/
|
|
USHORT
|
|
random_unit (USHORT type)
|
|
{
|
|
USHORT number;
|
|
|
|
/*
|
|
* Sometimes, we are asked to explicitly get a vowel (i.e., if
|
|
* a digram pair expects one following it). This is a shortcut
|
|
* to do that and avoid looping with rejected consonants.
|
|
*/
|
|
if (type & VOWEL)
|
|
number = vowel_numbers[get_random (0, (sizeof (vowel_numbers) / sizeof (USHORT))-1)];
|
|
else
|
|
/*
|
|
* Get any letter according to the English distribution.
|
|
*/
|
|
number = numbers[get_random (0, (sizeof (numbers) / sizeof (USHORT))-1)];
|
|
return (number);
|
|
}
|
|
|
|
|
|
/*
|
|
** get_random() -
|
|
** This routine should return a uniformly distributed Random number between
|
|
** minlen and maxlen inclusive. The Electronic Code Book form of CAST is
|
|
** used to produce the Random number. The inputs to CAST are the old pass-
|
|
** word and a pseudoRandom key generated according to the procedure out-
|
|
** lined in Appendix C of ANSI X9.17.
|
|
** INPUT:
|
|
** USHORT - minimum
|
|
** USHORT - maximum
|
|
** OUTPUT:
|
|
** USHORT - random number
|
|
** NOTES:
|
|
** none.
|
|
*/
|
|
|
|
USHORT
|
|
get_random (USHORT minlen, USHORT maxlen)
|
|
{
|
|
USHORT ret = 0;
|
|
ret = minlen + (USHORT) randint ((int) (maxlen - minlen + 1));
|
|
return (ret);
|
|
}
|
|
|