1 /* OpenBSD S/Key (put.c) 2 * 3 * Authors: 4 * Neil M. Haller <nmh@thumper.bellcore.com> 5 * Philip R. Karn <karn@chicago.qualcomm.com> 6 * John S. Walden <jsw@thumper.bellcore.com> 7 * Scott Chasin <chasin@crimelab.com> 8 * 9 * Dictionary lookup and extraction. 10 * 11 * $OpenBSD: put.c,v 1.10 2001/06/20 22:17:21 millert Exp $ 12 */ 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <assert.h> 18 #include <ctype.h> 19 20 #include "skey.h" 21 22 static unsigned int extract __P((char *, int, int)); 23 static void standard __P((char *)); 24 static void insert __P((char *, int, int, int)); 25 static int wsrch __P((char *, int, int)); 26 27 /* Standard dictionary for integer-word translations */ 28 static const char * const Wp[2048] = { 29 "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", 30 "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", 31 "AMY", "AN", "ANA", "AND", "ANN", "ANT", "ANY", 32 "APE", "APS", "APT", "ARC", "ARE", "ARK", "ARM", 33 "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", 34 "AUK", "AVE", "AWE", "AWK", "AWL", "AWN", "AX", 35 "AYE", "BAD", "BAG", "BAH", "BAM", "BAN", "BAR", 36 "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", 37 "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", 38 "BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", 39 "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", 40 "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", 41 "CAP", "CAR", "CAT", "CAW", "COD", "COG", "COL", 42 "CON", "COO", "COP", "COT", "COW", "COY", "CRY", 43 "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", 44 "DAM", "DAN", "DAR", "DAY", "DEE", "DEL", "DEN", 45 "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP", 46 "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", 47 "DUB", "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", 48 "ED", "EEL", "EGG", "EGO", "ELI", "ELK", "ELM", 49 "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", 50 "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", 51 "FED", "FEE", "FEW", "FIB", "FIG", "FIN", "FIR", 52 "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", "FRY", 53 "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", 54 "GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", 55 "GET", "GIG", "GIL", "GIN", "GO", "GOT", "GUM", 56 "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", 57 "HAD", "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", 58 "HAW", "HAY", "HE", "HEM", "HEN", "HER", "HEW", 59 "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", 60 "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", 61 "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT", 62 "I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", 63 "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", 64 "IS", "IT", "ITS", "IVY", "JAB", "JAG", "JAM", 65 "JAN", "JAR", "JAW", "JAY", "JET", "JIG", "JIM", 66 "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", 67 "JUT", "KAY", "KEG", "KEN", "KEY", "KID", "KIM", 68 "KIN", "KIT", "LA", "LAB", "LAC", "LAD", "LAG", 69 "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", 70 "LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", 71 "LIN", "LIP", "LIT", "LO", "LOB", "LOG", "LOP", 72 "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE", 73 "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", 74 "MAT", "MAW", "MAY", "ME", "MEG", "MEL", "MEN", 75 "MET", "MEW", "MID", "MIN", "MIT", "MOB", "MOD", 76 "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", 77 "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP", 78 "NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", 79 "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", 80 "NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", 81 "NUT", "O", "OAF", "OAK", "OAR", "OAT", "ODD", 82 "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK", 83 "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", 84 "OS", "OTT", "OUR", "OUT", "OVA", "OW", "OWE", 85 "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM", 86 "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", 87 "PEG", "PEN", "PEP", "PER", "PET", "PEW", "PHI", 88 "PI", "PIE", "PIN", "PIT", "PLY", "PO", "POD", 89 "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", 90 "PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", 91 "RAN", "RAP", "RAT", "RAW", "RAY", "REB", "RED", 92 "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO", 93 "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", 94 "ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", 95 "SAC", "SAD", "SAG", "SAL", "SAM", "SAN", "SAP", 96 "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", 97 "SET", "SEW", "SHE", "SHY", "SIN", "SIP", "SIR", 98 "SIS", "SIT", "SKI", "SKY", "SLY", "SO", "SOB", 99 "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", 100 "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", 101 "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED", 102 "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", 103 "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", 104 "TOO", "TOP", "TOW", "TOY", "TRY", "TUB", "TUG", 105 "TUM", "TUN", "TWO", "UN", "UP", "US", "USE", 106 "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", 107 "WAS", "WAY", "WE", "WEB", "WED", "WEE", "WET", 108 "WHO", "WHY", "WIN", "WIT", "WOK", "WON", "WOO", 109 "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", 110 "YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", 111 "ABLE", "ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", 112 "ACTS", "ADAM", "ADDS", "ADEN", "AFAR", "AFRO", "AGEE", 113 "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR", 114 "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", 115 "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN", "AMES", 116 "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW", 117 "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", 118 "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", 119 "ASKS", "ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", 120 "AVIS", "AVON", "AVOW", "AWAY", "AWRY", "BABE", "BABY", 121 "BACH", "BACK", "BADE", "BAIL", "BAIT", "BAKE", "BALD", 122 "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE", 123 "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", 124 "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", 125 "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", 126 "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", 127 "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", 128 "BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", 129 "BIDE", "BIEN", "BILE", "BILK", "BILL", "BIND", "BING", 130 "BIRD", "BITE", "BITS", "BLAB", "BLAT", "BLED", "BLEW", 131 "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR", 132 "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", 133 "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", 134 "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", 135 "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", 136 "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", 137 "BRAN", "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", 138 "BUCK", "BUDD", "BUFF", "BULB", "BULK", "BULL", "BUNK", 139 "BUNT", "BUOY", "BURG", "BURL", "BURN", "BURR", "BURT", 140 "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY", 141 "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", 142 "CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", 143 "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", 144 "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", 145 "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", 146 "CHUB", "CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", 147 "CLAN", "CLAW", "CLAY", "CLOD", "CLOG", "CLOT", "CLUB", 148 "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO", "CODA", 149 "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", 150 "COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", 151 "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST", 152 "COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", 153 "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", 154 "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", 155 "CUTS", "DADE", "DALE", "DAME", "DANA", "DANE", "DANG", 156 "DANK", "DARE", "DARK", "DARN", "DART", "DASH", "DATA", 157 "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF", 158 "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", 159 "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", 160 "DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", 161 "DINT", "DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", 162 "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME", "DONE", 163 "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", 164 "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", 165 "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL", 166 "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", 167 "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", 168 "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", 169 "EDIT", "EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", 170 "EMIL", "EMIT", "EMMA", "ENDS", "ERIC", "EROS", "EVEN", 171 "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE", "FAIL", 172 "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", 173 "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", 174 "FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", 175 "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", 176 "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", 177 "FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", 178 "FLED", "FLEW", "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", 179 "FLUE", "FOAL", "FOAM", "FOGY", "FOIL", "FOLD", "FOLK", 180 "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", "FORE", 181 "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", 182 "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", 183 "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", 184 "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", 185 "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", 186 "GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", 187 "GEAR", "GELD", "GENE", "GENT", "GERM", "GETS", "GIBE", 188 "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD", "GIRL", 189 "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB", 190 "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", 191 "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", 192 "GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", 193 "GRAB", "GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", 194 "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL", 195 "GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", 196 "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF", "HALL", 197 "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD", 198 "HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", 199 "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", 200 "HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", 201 "HELL", "HELM", "HERB", "HERD", "HERE", "HERO", "HERS", 202 "HESS", "HEWN", "HICK", "HIDE", "HIGH", "HIKE", "HILL", 203 "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO", 204 "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", 205 "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN", 206 "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", 207 "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", 208 "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", 209 "HYDE", "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", 210 "INCA", "INCH", "INTO", "IONS", "IOTA", "IOWA", "IRIS", 211 "IRMA", "IRON", "ISLE", "ITCH", "ITEM", "IVAN", "JACK", 212 "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF", 213 "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", 214 "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", 215 "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", 216 "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", 217 "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", 218 "KATE", "KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", 219 "KEYS", "KICK", "KILL", "KIND", "KING", "KIRK", "KISS", 220 "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB", "KNOT", 221 "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", 222 "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", 223 "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", 224 "LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", 225 "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", 226 "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", 227 "LESK", "LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", 228 "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT", "LIKE", 229 "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND", 230 "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", 231 "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", 232 "LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", 233 "LORD", "LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", 234 "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU", "LUND", 235 "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", 236 "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", 237 "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT", 238 "MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", 239 "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", 240 "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", 241 "MEEK", "MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", 242 "MERT", "MESH", "MESS", "MICE", "MIKE", "MILD", "MILE", 243 "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE", "MINI", 244 "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", 245 "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", 246 "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", 247 "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", 248 "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", 249 "MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", 250 "NAGY", "NAIL", "NAIR", "NAME", "NARY", "NASH", "NAVE", 251 "NAVY", "NEAL", "NEAR", "NEAT", "NECK", "NEED", "NEIL", 252 "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", "NEWT", 253 "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", 254 "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", 255 "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", 256 "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", 257 "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", 258 "OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", 259 "ORGY", "OSLO", "OTIS", "OTTO", "OUCH", "OUST", "OUTS", 260 "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD", "QUIT", 261 "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID", 262 "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", 263 "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", 264 "RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", 265 "RENA", "REND", "RENT", "REST", "RICE", "RICH", "RICK", 266 "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE", 267 "RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", 268 "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF", "ROOK", 269 "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH", 270 "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", 271 "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", 272 "RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", 273 "SAGE", "SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", 274 "SAND", "SANE", "SANG", "SANK", "SARA", "SAUL", "SAVE", 275 "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM", 276 "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", 277 "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG", 278 "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", 279 "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", 280 "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", 281 "SINE", "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", 282 "SKAT", "SKEW", "SKID", "SKIM", "SKIN", "SKIT", "SLAB", 283 "SLAM", "SLAT", "SLAY", "SLED", "SLEW", "SLID", "SLIM", 284 "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM", 285 "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", 286 "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", 287 "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", 288 "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", 289 "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", 290 "STUN", "SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", 291 "SUNK", "SURE", "SURF", "SWAB", "SWAG", "SWAM", "SWAN", 292 "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT", "TAIL", 293 "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", 294 "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", 295 "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS", 296 "TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", 297 "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", 298 "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", 299 "TINE", "TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", 300 "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK", "TOOL", 301 "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN", 302 "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", 303 "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", 304 "TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", 305 "TUSK", "TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", 306 "USED", "USER", "USES", "UTAH", "VAIL", "VAIN", "VALE", 307 "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", 308 "VEND", "VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", 309 "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE", 310 "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", 311 "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM", 312 "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", 313 "WAVY", "WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", 314 "WEEK", "WEIR", "WELD", "WELL", "WELT", "WENT", "WERE", 315 "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN", "WHET", 316 "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", 317 "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", 318 "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", 319 "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", 320 "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", 321 "YEAR", "YELL", "YOGA", "YOKE" 322 }; 323 324 /* 325 * Encode 8 bytes in 'c' as a string of English words. 326 * Returns a pointer to a static buffer 327 */ 328 char * 329 btoe(engout, c) 330 char *engout; 331 char *c; 332 { 333 char cp[10]; /* add in room for the parity 2 bits + extract() slop */ 334 int p, i, indices[6]; 335 336 /* workaround for extract() reads beyond end of data */ 337 (void)memset(cp, 0, sizeof(cp)); 338 (void)memcpy(cp, c, 8); 339 340 /* compute parity */ 341 for (p = 0, i = 0; i < 64; i += 2) 342 p += extract(cp, i, 2); 343 344 cp[8] = (char)p << 6; 345 346 indices[0] = extract(cp, 0, 11); 347 indices[1] = extract(cp, 11, 11); 348 indices[2] = extract(cp, 22, 11); 349 indices[3] = extract(cp, 33, 11); 350 indices[4] = extract(cp, 44, 11); 351 indices[5] = extract(cp, 55, 11); 352 353 sprintf(engout, "%.4s %.4s %.4s %.4s %.4s %.4s", Wp[indices[0]], 354 Wp[indices[1]], Wp[indices[2]], Wp[indices[3]], 355 Wp[indices[4]], Wp[indices[5]]); 356 357 return(engout); 358 } 359 360 /* 361 * convert English to binary 362 * returns 1 OK - all good words and parity is OK 363 * 0 word not in data base 364 * -1 badly formed in put ie > 4 char word 365 * -2 words OK but parity is wrong 366 */ 367 int 368 etob(out, e) 369 char *out; 370 char *e; 371 { 372 char *word; 373 int i, p, v, l, low, high; 374 char b[SKEY_BINKEY_SIZE+1]; 375 char input[36]; 376 377 if (e == NULL) 378 return(-1); 379 380 (void)strncpy(input, e, sizeof(input) - 1); 381 input[sizeof(input) - 1] = '\0'; 382 (void)memset(b, 0, sizeof(b)); 383 (void)memset(out, 0, SKEY_BINKEY_SIZE); 384 for (i = 0, p = 0; i < 6; i++, p += 11) { 385 if ((word = strtok(i == 0 ? input : NULL, " ")) == NULL) 386 return(-1); 387 388 l = strlen(word); 389 if (l > 4 || l < 1) { 390 return(-1); 391 } else if (l < 4) { 392 low = 0; 393 high = 570; 394 } else { 395 low = 571; 396 high = 2047; 397 } 398 standard(word); 399 400 if ((v = wsrch(word, low, high)) < 0) 401 return(0); 402 403 insert(b, v, p, 11); 404 } 405 406 /* now check the parity of what we got */ 407 for (p = 0, i = 0; i < 64; i += 2) 408 p += extract(b, i, 2); 409 410 if ((p & 3) != extract(b, 64, 2)) 411 return(-2); 412 413 (void)memcpy(out, b, SKEY_BINKEY_SIZE); 414 415 return(1); 416 } 417 418 /* Display 8 bytes as a series of 16-bit hex digits */ 419 char * 420 put8(out, s) 421 char *out; 422 char *s; 423 { 424 (void)sprintf(out, "%02X%02X %02X%02X %02X%02X %02X%02X", 425 s[0] & 0xff, s[1] & 0xff, s[2] & 0xff, 426 s[3] & 0xff, s[4] & 0xff, s[5] & 0xff, 427 s[6] & 0xff, s[7] & 0xff); 428 return(out); 429 } 430 431 /* Internal subroutines for word encoding/decoding */ 432 433 /* Dictionary binary search */ 434 static int 435 wsrch(w, low, high) 436 char *w; 437 int low; 438 int high; 439 { 440 int i, j; 441 442 for (;;) { 443 i = (low + high) / 2; 444 445 if ((j = strncmp(w, Wp[i], 4)) == 0) 446 return(i); /* Found it */ 447 448 if (high == low + 1) { 449 /* Avoid effects of integer truncation in /2 */ 450 if (strncmp(w, Wp[high], 4) == 0) 451 return(high); 452 else 453 return(-1); 454 } 455 456 if (low >= high) 457 return(-1); /* I don't *think* this can happen... */ 458 if (j < 0) 459 high = i; /* Search lower half */ 460 else 461 low = i; /* Search upper half */ 462 } 463 } 464 465 static void 466 insert(s, x, start, length) 467 char *s; 468 int x; 469 int start; 470 int length; 471 { 472 unsigned char cl; 473 unsigned char cc; 474 unsigned char cr; 475 unsigned int y; 476 int shift; 477 478 assert(length <= 11); 479 assert(start >= 0); 480 assert(length >= 0); 481 assert(start + length <= 66); 482 483 shift = ((8 - ((start + length) % 8)) % 8); 484 y = x << shift; 485 cl = (y >> 16) & 0xff; 486 cc = (y >> 8) & 0xff; 487 cr = y & 0xff; 488 if (shift + length > 16) { 489 s[start / 8] |= cl; 490 s[start / 8 + 1] |= cc; 491 s[start / 8 + 2] |= cr; 492 } else if (shift + length > 8) { 493 s[start / 8] |= cc; 494 s[start / 8 + 1] |= cr; 495 } else { 496 s[start / 8] |= cr; 497 } 498 } 499 500 static void 501 standard(word) 502 char *word; 503 { 504 505 while (*word) { 506 if (!isascii(*word)) 507 break; 508 if (islower(*word)) 509 *word = toupper(*word); 510 if (*word == '1') 511 *word = 'L'; 512 if (*word == '0') 513 *word = 'O'; 514 if (*word == '5') 515 *word = 'S'; 516 word++; 517 } 518 } 519 520 /* Extract 'length' bits from the char array 's' starting with bit 'start' */ 521 static unsigned int 522 extract(s, start, length) 523 char *s; 524 int start; 525 int length; 526 { 527 unsigned char cl; 528 unsigned char cc; 529 unsigned char cr; 530 unsigned int x; 531 532 assert(length <= 11); 533 assert(start >= 0); 534 assert(length >= 0); 535 assert(start + length <= 66); 536 537 cl = s[start / 8]; 538 cc = s[start / 8 + 1]; 539 cr = s[start / 8 + 2]; 540 x = ((int)(cl << 8 | cc) << 8 | cr); 541 x = x >> (24 - (length + (start % 8))); 542 x = (x & (0xffff >> (16 - length))); 543 544 return(x); 545 } 546