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