/* ** Copyright (c) 2008 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains the code to do mnemonic encoding of commit IDs. The ** wordlist and algorithm were originally taken from: ** ** https://github.com/singpolyma/mnemonicode ** ** ...which is BSD licensed. However, the algorithm has since been heavily ** modified to more fit Fossil's special needs. ** ** The new algorithm works by reading hex characters one at a time and ** accumulating bits into a ring buffer. When available, 10 bits are consumed ** and used as a word index. This only uses 1024 of the available 1626 words ** but preserves the property that encoded strings may be truncated at any ** point and the resulting hex string, when decoded, is a truncated form of ** the original hex string. It is, unfortunately, slightly less efficient, and ** three words can only encode seven hex digits. */ #include "config.h" #include "mnemonic.h" #define MN_BASE 1626 /* Number of bits to encode as a word. 10 is the maximum. */ #define CHUNK_SIZE 10 static const char* basewordlist[MN_BASE] = { "ACADEMY", "ACROBAT", "ACTIVE", "ACTOR", "ADAM", "ADMIRAL", "ADRIAN", "AFRICA", "AGENDA", "AGENT", "AIRLINE", "AIRPORT", "ALADDIN", "ALARM", "ALASKA", "ALBERT", "ALBINO", "ALBUM", "ALCOHOL", "ALEX", "ALGEBRA", "ALIBI", "ALICE", "ALIEN", "ALPHA", "ALPINE", "AMADEUS", "AMANDA", "AMAZON", "AMBER", "AMERICA", "AMIGO", "ANALOG", "ANATOMY", "ANGEL", "ANIMAL", "ANTENNA", "ANTONIO", "APOLLO", "APRIL", "ARCHIVE", "ARCTIC", "ARIZONA", "ARNOLD", "AROMA", "ARTHUR", "ARTIST", "ASIA", "ASPECT", "ASPIRIN", "ATHENA", "ATHLETE", "ATLAS", "AUDIO", "AUGUST", "AUSTRIA", "AXIOM", "AZTEC", "BALANCE", "BALLAD", "BANANA", "BANDIT", "BANJO", "BARCODE", "BARON", "BASIC", "BATTERY", "BELGIUM", "BERLIN", "BERMUDA", "BERNARD", "BIKINI", "BINARY", "BINGO", "BIOLOGY", "BLOCK", "BLONDE", "BONUS", "BORIS", "BOSTON", "BOXER", "BRANDY", "BRAVO", "BRAZIL", "BRONZE", "BROWN", "BRUCE", "BRUNO", "BURGER", "BURMA", "CABINET", "CACTUS", "CAFE", "CAIRO", "CAKE", "CALYPSO", "CAMEL", "CAMERA", "CAMPUS", "CANADA", "CANAL", "CANNON", "CANOE", "CANTINA", "CANVAS", "CANYON", "CAPITAL", "CARAMEL", "CARAVAN", "CARBON", "CARGO", "CARLO", "CAROL", "CARPET", "CARTEL", "CASINO", "CASTLE", "CASTRO", "CATALOG", "CAVIAR", "CECILIA", "CEMENT", "CENTER", "CENTURY", "CERAMIC", "CHAMBER", "CHANCE", "CHANGE", "CHAOS", "CHARLIE", "CHARM", "CHARTER", "CHEF", "CHEMIST", "CHERRY", "CHESS", "CHICAGO", "CHICKEN", "CHIEF", "CHINA", "CIGAR", "CINEMA", "CIRCUS", "CITIZEN", "CITY", "CLARA", "CLASSIC", "CLAUDIA", "CLEAN", "CLIENT", "CLIMAX", "CLINIC", "CLOCK", "CLUB", "COBRA", "COCONUT", "COLA", "COLLECT", "COLOMBO", "COLONY", "COLOR", "COMBAT", "COMEDY", "COMET", "COMMAND", "COMPACT", "COMPANY", "COMPLEX", "CONCEPT", "CONCERT", "CONNECT", "CONSUL", "CONTACT", "CONTEXT", "CONTOUR", "CONTROL", "CONVERT", "COPY", "CORNER", "CORONA", "CORRECT", "COSMOS", "COUPLE", "COURAGE", "COWBOY", "CRAFT", "CRASH", "CREDIT", "CRICKET", "CRITIC", "CROWN", "CRYSTAL", "CUBA", "CULTURE", "DALLAS", "DANCE", "DANIEL", "DAVID", "DECADE", "DECIMAL", "DELIVER", "DELTA", "DELUXE", "DEMAND", "DEMO", "DENMARK", "DERBY", "DESIGN", "DETECT", "DEVELOP", "DIAGRAM", "DIALOG", "DIAMOND", "DIANA", "DIEGO", "DIESEL", "DIET", "DIGITAL", "DILEMMA", "DIPLOMA", "DIRECT", "DISCO", "DISNEY", "DISTANT", "DOCTOR", "DOLLAR", "DOMINIC", "DOMINO", "DONALD", "DRAGON", "DRAMA", "DUBLIN", "DUET", "DYNAMIC", "EAST", "ECOLOGY", "ECONOMY", "EDGAR", "EGYPT", "ELASTIC", "ELEGANT", "ELEMENT", "ELITE", "ELVIS", "EMAIL", "ENERGY", "ENGINE", "ENGLISH", "EPISODE", "EQUATOR", "ESCORT", "ETHNIC", "EUROPE", "EVEREST", "EVIDENT", "EXACT", "EXAMPLE", "EXIT", "EXOTIC", "EXPORT", "EXPRESS", "EXTRA", "FABRIC", "FACTOR", "FALCON", "FAMILY", "FANTASY", "FASHION", "FIBER", "FICTION", "FIDEL", "FIESTA", "FIGURE", "FILM", "FILTER", "FINAL", "FINANCE", "FINISH", "FINLAND", "FLASH", "FLORIDA", "FLOWER", "FLUID", "FLUTE", "FOCUS", "FORD", "FOREST", "FORMAL", "FORMAT", "FORMULA", "FORTUNE", "FORUM", "FRAGILE", "FRANCE", "FRANK", "FRIEND", "FROZEN", "FUTURE", "GABRIEL", "GALAXY", "GALLERY", "GAMMA", "GARAGE", "GARDEN", "GARLIC", "GEMINI", "GENERAL", "GENETIC", "GENIUS", "GERMANY", "GLOBAL", "GLORIA", "GOLF", "GONDOLA", "GONG", "GOOD", "GORDON", "GORILLA", "GRAND", "GRANITE", "GRAPH", "GREEN", "GROUP", "GUIDE", "GUITAR", "GURU", "HAND", "HAPPY", "HARBOR", "HARMONY", "HARVARD", "HAVANA", "HAWAII", "HELENA", "HELLO", "HENRY", "HILTON", "HISTORY", "HORIZON", "HOTEL", "HUMAN", "HUMOR", "ICON", "IDEA", "IGLOO", "IGOR", "IMAGE", "IMPACT", "IMPORT", "INDEX", "INDIA", "INDIGO", "INPUT", "INSECT", "INSTANT", "IRIS", "ITALIAN", "JACKET", "JACOB", "JAGUAR", "JANET", "JAPAN", "JARGON", "JAZZ", "JEEP", "JOHN", "JOKER", "JORDAN", "JUMBO", "JUNE", "JUNGLE", "JUNIOR", "JUPITER", "KARATE", "KARMA", "KAYAK", "KERMIT", "KILO", "KING", "KOALA", "KOREA", "LABOR", "LADY", "LAGOON", "LAPTOP", "LASER", "LATIN", "LAVA", "LECTURE", "LEFT", "LEGAL", "LEMON", "LEVEL", "LEXICON", "LIBERAL", "LIBRA", "LIMBO", "LIMIT", "LINDA", "LINEAR", "LION", "LIQUID", "LITER", "LITTLE", "LLAMA", "LOBBY", "LOBSTER", "LOCAL", "LOGIC", "LOGO", "LOLA", "LONDON", "LOTUS", "LUCAS", "LUNAR", "MACHINE", "MACRO", "MADAM", "MADONNA", "MADRID", "MAESTRO", "MAGIC", "MAGNET", "MAGNUM", "MAJOR", "MAMA", "MAMBO", "MANAGER", "MANGO", "MANILA", "MARCO", "MARINA", "MARKET", "MARS", "MARTIN", "MARVIN", "MASTER", "MATRIX", "MAXIMUM", "MEDIA", "MEDICAL", "MEGA", "MELODY", "MELON", "MEMO", "MENTAL", "MENTOR", "MENU", "MERCURY", "MESSAGE", "METAL", "METEOR", "METER", "METHOD", "METRO", "MEXICO", "MIAMI", "MICRO", "MILLION", "MINERAL", "MINIMUM", "MINUS", "MINUTE", "MIRACLE", "MIRAGE", "MIRANDA", "MISTER", "MIXER", "MOBILE", "MODEL", "MODEM", "MODERN", "MODULAR", "MOMENT", "MONACO", "MONICA", "MONITOR", "MONO", "MONSTER", "MONTANA", "MORGAN", "MOTEL", "MOTIF", "MOTOR", "MOZART", "MULTI", "MUSEUM", "MUSIC", "MUSTANG", "NATURAL", "NEON", "NEPAL", "NEPTUNE", "NERVE", "NEUTRAL", "NEVADA", "NEWS", "NINJA", "NIRVANA", "NORMAL", "NOVA", "NOVEL", "NUCLEAR", "NUMERIC", "NYLON", "OASIS", "OBJECT", "OBSERVE", "OCEAN", "OCTOPUS", "OLIVIA", "OLYMPIC", "OMEGA", "OPERA", "OPTIC", "OPTIMAL", "ORANGE", "ORBIT", "ORGANIC", "ORIENT", "ORIGIN", "ORLANDO", "OSCAR", "OXFORD", "OXYGEN", "OZONE", "PABLO", "PACIFIC", "PAGODA", "PALACE", "PAMELA", "PANAMA", "PANDA", "PANEL", "PANIC", "PARADOX", "PARDON", "PARIS", "PARKER", "PARKING", "PARODY", "PARTNER", "PASSAGE", "PASSIVE", "PASTA", "PASTEL", "PATENT", "PATRIOT", "PATROL", "PATRON", "PEGASUS", "PELICAN", "PENGUIN", "PEPPER", "PERCENT", "PERFECT", "PERFUME", "PERIOD", "PERMIT", "PERSON", "PERU", "PHONE", "PHOTO", "PIANO", "PICASSO", "PICNIC", "PICTURE", "PIGMENT", "PILGRIM", "PILOT", "PIRATE", "PIXEL", "PIZZA", "PLANET", "PLASMA", "PLASTER", "PLASTIC", "PLAZA", "POCKET", "POEM", "POETIC", "POKER", "POLARIS", "POLICE", "POLITIC", "POLO", "POLYGON", "PONY", "POPCORN", "POPULAR", "POSTAGE", "POSTAL", "PRECISE", "PREFIX", "PREMIUM", "PRESENT", "PRICE", "PRINCE", "PRINTER", "PRISM", "PRIVATE", "PRODUCT", "PROFILE", "PROGRAM", "PROJECT", "PROTECT", "PROTON", "PUBLIC", "PULSE", "PUMA", "PYRAMID", "QUEEN", "RADAR", "RADIO", "RANDOM", "RAPID", "REBEL", "RECORD", "RECYCLE", "REFLEX", "REFORM", "REGARD", "REGULAR", "RELAX", "REPORT", "REPTILE", "REVERSE", "RICARDO", "RINGO", "RITUAL", "ROBERT", "ROBOT", "ROCKET", "RODEO", "ROMEO", "ROYAL", "RUSSIAN", "SAFARI", "SALAD", "SALAMI", "SALMON", "SALON", "SALUTE", "SAMBA", "SANDRA", "SANTANA", "SARDINE", "SCHOOL", "SCREEN", "SCRIPT", "SECOND", "SECRET", "SECTION", "SEGMENT", "SELECT", "SEMINAR", "SENATOR", "SENIOR", "SENSOR", "SERIAL", "SERVICE", "SHERIFF", "SHOCK", "SIERRA", "SIGNAL", "SILICON", "SILVER", "SIMILAR", "SIMON", "SINGLE", "SIREN", "SLOGAN", "SOCIAL", "SODA", "SOLAR", "SOLID", "SOLO", "SONIC", "SOVIET", "SPECIAL", "SPEED", "SPIRAL", "SPIRIT", "SPORT", "STATIC", "STATION", "STATUS", "STEREO", "STONE", "STOP", "STREET", "STRONG", "STUDENT", "STUDIO", "STYLE", "SUBJECT", "SULTAN", "SUPER", "SUSAN", "SUSHI", "SUZUKI", "SWITCH", "SYMBOL", "SYSTEM", "TACTIC", "TAHITI", "TALENT", "TANGO", "TARZAN", "TAXI", "TELEX", "TEMPO", "TENNIS", "TEXAS", "TEXTILE", "THEORY", "THERMOS", "TIGER", "TITANIC", "TOKYO", "TOMATO", "TOPIC", "TORNADO", "TORONTO", "TORPEDO", "TOTAL", "TOTEM", "TOURIST", "TRACTOR", "TRAFFIC", "TRANSIT", "TRAPEZE", "TRAVEL", "TRIBAL", "TRICK", "TRIDENT", "TRILOGY", "TRIPOD", "TROPIC", "TRUMPET", "TULIP", "TUNA", "TURBO", "TWIST", "ULTRA", "UNIFORM", "UNION", "URANIUM", "VACUUM", "VALID", "VAMPIRE", "VANILLA", "VATICAN", "VELVET", "VENTURA", "VENUS", "VERTIGO", "VETERAN", "VICTOR", "VIDEO", "VIENNA", "VIKING", "VILLAGE", "VINCENT", "VIOLET", "VIOLIN", "VIRTUAL", "VIRUS", "VISA", "VISION", "VISITOR", "VISUAL", "VITAMIN", "VIVA", "VOCAL", "VODKA", "VOLCANO", "VOLTAGE", "VOLUME", "VOYAGE", "WATER", "WEEKEND", "WELCOME", "WESTERN", "WINDOW", "WINTER", "WIZARD", "WOLF", "WORLD", "XRAY", "YANKEE", "YOGA", "YOGURT", "YOYO", "ZEBRA", "ZERO", "ZIGZAG", "ZIPPER", "ZODIAC", "ZOOM", "ABRAHAM", "ACTION", "ADDRESS", "ALABAMA", "ALFRED", "ALMOND", "AMMONIA", "ANALYZE", "ANNUAL", "ANSWER", "APPLE", "ARENA", "ARMADA", "ARSENAL", "ATLANTA", "ATOMIC", "AVENUE", "AVERAGE", "BAGEL", "BAKER", "BALLET", "BAMBINO", "BAMBOO", "BARBARA", "BASKET", "BAZAAR", "BENEFIT", "BICYCLE", "BISHOP", "BLITZ", "BONJOUR", "BOTTLE", "BRIDGE", "BRITISH", "BROTHER", "BRUSH", "BUDGET", "CABARET", "CADET", "CANDLE", "CAPITAN", "CAPSULE", "CAREER", "CARTOON", "CHANNEL", "CHAPTER", "CHEESE", "CIRCLE", "COBALT", "COCKPIT", "COLLEGE", "COMPASS", "COMRADE", "CONDOR", "CRIMSON", "CYCLONE", "DARWIN", "DECLARE", "DEGREE", "DELETE", "DELPHI", "DENVER", "DESERT", "DIVIDE", "DOLBY", "DOMAIN", "DOMINGO", "DOUBLE", "DRINK", "DRIVER", "EAGLE", "EARTH", "ECHO", "ECLIPSE", "EDITOR", "EDUCATE", "EDWARD", "EFFECT", "ELECTRA", "EMERALD", "EMOTION", "EMPIRE", "EMPTY", "ESCAPE", "ETERNAL", "EVENING", "EXHIBIT", "EXPAND", "EXPLORE", "EXTREME", "FERRARI", "FIRST", "FLAG", "FOLIO", "FORGET", "FORWARD", "FREEDOM", "FRESH", "FRIDAY", "FUJI", "GALILEO", "GARCIA", "GENESIS", "GOLD", "GRAVITY", "HABITAT", "HAMLET", "HARLEM", "HELIUM", "HOLIDAY", "HOUSE", "HUNTER", "IBIZA", "ICEBERG", "IMAGINE", "INFANT", "ISOTOPE", "JACKSON", "JAMAICA", "JASMINE", "JAVA", "JESSICA", "JUDO", "KITCHEN", "LAZARUS", "LETTER", "LICENSE", "LITHIUM", "LOYAL", "LUCKY", "MAGENTA", "MAILBOX", "MANUAL", "MARBLE", "MARY", "MAXWELL", "MAYOR", "MILK", "MONARCH", "MONDAY", "MONEY", "MORNING", "MOTHER", "MYSTERY", "NATIVE", "NECTAR", "NELSON", "NETWORK", "NEXT", "NIKITA", "NOBEL", "NOBODY", "NOMINAL", "NORWAY", "NOTHING", "NUMBER", "OCTOBER", "OFFICE", "OLIVER", "OPINION", "OPTION", "ORDER", "OUTSIDE", "PACKAGE", "PANCAKE", "PANDORA", "PANTHER", "PAPA", "PATIENT", "PATTERN", "PEDRO", "PENCIL", "PEOPLE", "PHANTOM", "PHILIPS", "PIONEER", "PLUTO", "PODIUM", "PORTAL", "POTATO", "PRIZE", "PROCESS", "PROTEIN", "PROXY", "PUMP", "PUPIL", "PYTHON", "QUALITY", "QUARTER", "QUIET", "RABBIT", "RADICAL", "RADIUS", "RAINBOW", "RALPH", "RAMIREZ", "RAVIOLI", "RAYMOND", "RESPECT", "RESPOND", "RESULT", "RESUME", "RETRO", "RICHARD", "RIGHT", "RISK", "RIVER", "ROGER", "ROMAN", "RONDO", "SABRINA", "SALARY", "SALSA", "SAMPLE", "SAMUEL", "SATURN", "SAVAGE", "SCARLET", "SCOOP", "SCORPIO", "SCRATCH", "SCROLL", "SECTOR", "SERPENT", "SHADOW", "SHAMPOO", "SHARON", "SHARP", "SHORT", "SHRINK", "SILENCE", "SILK", "SIMPLE", "SLANG", "SMART", "SMOKE", "SNAKE", "SOCIETY", "SONAR", "SONATA", "SOPRANO", "SOURCE", "SPARTA", "SPHERE", "SPIDER", "SPONSOR", "SPRING", "ACID", "ADIOS", "AGATHA", "ALAMO", "ALERT", "ALMANAC", "ALOHA", "ANDREA", "ANITA", "ARCADE", "AURORA", "AVALON", "BABY", "BAGGAGE", "BALLOON", "BANK", "BASIL", "BEGIN", "BISCUIT", "BLUE", "BOMBAY", "BRAIN", "BRENDA", "BRIGADE", "CABLE", "CARMEN", "CELLO", "CELTIC", "CHARIOT", "CHROME", "CITRUS", "CIVIL", "CLOUD", "COMMON", "COMPARE", "COOL", "COPPER", "CORAL", "CRATER", "CUBIC", "CUPID", "CYCLE", "DEPEND", "DOOR", "DREAM", "DYNASTY", "EDISON", "EDITION", "ENIGMA", "EQUAL", "ERIC", "EVENT", "EVITA", "EXODUS", "EXTEND", "FAMOUS", "FARMER", "FOOD", "FOSSIL", "FROG", "FRUIT", "GENEVA", "GENTLE", "GEORGE", "GIANT", "GILBERT", "GOSSIP", "GRAM", "GREEK", "GRILLE", "HAMMER", "HARVEST", "HAZARD", "HEAVEN", "HERBERT", "HEROIC", "HEXAGON", "HUSBAND", "IMMUNE", "INCA", "INCH", "INITIAL", "ISABEL", "IVORY", "JASON", "JEROME", "JOEL", "JOSHUA", "JOURNAL", "JUDGE", "JULIET", "JUMP", "JUSTICE", "KIMONO", "KINETIC", "LEONID", "LIMA", "MAZE", "MEDUSA", "MEMBER", "MEMPHIS", "MICHAEL", "MIGUEL", "MILAN", "MILE", "MILLER", "MIMIC", "MIMOSA", "MISSION", "MONKEY", "MORAL", "MOSES", "MOUSE", "NANCY", "NATASHA", "NEBULA", "NICKEL", "NINA", "NOISE", "ORCHID", "OREGANO", "ORIGAMI", "ORINOCO", "ORION", "OTHELLO", "PAPER", "PAPRIKA", "PRELUDE", "PREPARE", "PRETEND", "PROFIT", "PROMISE", "PROVIDE", "PUZZLE", "REMOTE", "REPAIR", "REPLY", "RIVAL", "RIVIERA", "ROBIN", "ROSE", "ROVER", "RUDOLF", "SAGA", "SAHARA", "SCHOLAR", "SHELTER", "SHIP", "SHOE", "SIGMA", "SISTER", "SLEEP", "SMILE", "SPAIN", "SPARK", "SPLIT", "SPRAY", "SQUARE", "STADIUM", "STAR", "STORM", "STORY", "STRANGE", "STRETCH", "STUART", "SUBWAY", "SUGAR", "SULFUR", "SUMMER", "SURVIVE", "SWEET", "SWIM", "TABLE", "TABOO", "TARGET", "TEACHER", "TELECOM", "TEMPLE", "TIBET", "TICKET", "TINA", "TODAY", "TOGA", "TOMMY", "TOWER", "TRIVIAL", "TUNNEL", "TURTLE", "TWIN", "UNCLE", "UNICORN", "UNIQUE", "UPDATE", "VALERY", "VEGA", "VERSION", "VOODOO", "WARNING", "WILLIAM", "WONDER", "YEAR", "YELLOW", "YOUNG", "ABSENT", "ABSORB", "ACCENT", "ALFONSO", "ALIAS", "AMBIENT", "ANDY", "ANVIL", "APPEAR", "APROPOS", "ARCHER", "ARIEL", "ARMOR", "ARROW", "AUSTIN", "AVATAR", "AXIS", "BABOON", "BAHAMA", "BALI", "BALSA", "BAZOOKA", "BEACH", "BEAST", "BEATLES", "BEAUTY", "BEFORE", "BENNY", "BETTY", "BETWEEN", "BEYOND", "BILLY", "BISON", "BLAST", "BLESS", "BOGART", "BONANZA", "BOOK", "BORDER", "BRAVE", "BREAD", "BREAK", "BROKEN", "BUCKET", "BUENOS", "BUFFALO", "BUNDLE", "BUTTON", "BUZZER", "BYTE", "CAESAR", "CAMILLA", "CANARY", "CANDID", "CARROT", "CAVE", "CHANT", "CHILD", "CHOICE", "CHRIS", "CIPHER", "CLARION", "CLARK", "CLEVER", "CLIFF", "CLONE", "CONAN", "CONDUCT", "CONGO", "CONTENT", "COSTUME", "COTTON", "COVER", "CRACK", "CURRENT", "DANUBE", "DATA", "DECIDE", "DESIRE", "DETAIL", "DEXTER", "DINNER", "DISPUTE", "DONOR", "DRUID", "DRUM", "EASY", "EDDIE", "ENJOY", "ENRICO", "EPOXY", "EROSION", "EXCEPT", "EXILE", "EXPLAIN", "FAME", "FAST", "FATHER", "FELIX", "FIELD", "FIONA", "FIRE", "FISH", "FLAME", "FLEX", "FLIPPER", "FLOAT", "FLOOD", "FLOOR", "FORBID", "FOREVER", "FRACTAL", "FRAME", "FREDDIE", "FRONT", "FUEL", "GALLOP", "GAME", "GARBO", "GATE", "GIBSON", "GINGER", "GIRAFFE", "GIZMO", "GLASS", "GOBLIN", "GOPHER", "GRACE", "GRAY", "GREGORY", "GRID", "GRIFFIN", "GROUND", "GUEST", "GUSTAV", "GYRO", "HAIR", "HALT", "HARRIS", "HEART", "HEAVY", "HERMAN", "HIPPIE", "HOBBY", "HONEY", "HOPE", "HORSE", "HOSTEL", "HYDRO", "IMITATE", "INFO", "INGRID", "INSIDE", "INVENT", "INVEST", "INVITE", "IRON", "IVAN", "JAMES", "JESTER", "JIMMY", "JOIN", "JOSEPH", "JUICE", "JULIUS", "JULY", "JUSTIN", "KANSAS", "KARL", "KEVIN", "KIWI", "LADDER", "LAKE", "LAURA", "LEARN", "LEGACY", "LEGEND", "LESSON", "LIFE", "LIGHT", "LIST", "LOCATE", "LOPEZ", "LORENZO", "LOVE", "LUNCH", "MALTA", "MAMMAL", "MARGO", "MARION", "MASK", "MATCH", "MAYDAY", "MEANING", "MERCY", "MIDDLE", "MIKE", "MIRROR", "MODEST", "MORPH", "MORRIS", "NADIA", "NATO", "NAVY", "NEEDLE", "NEURON", "NEVER", "NEWTON", "NICE", "NIGHT", "NISSAN", "NITRO", "NIXON", "NORTH", "OBERON", "OCTAVIA", "OHIO", "OLGA", "OPEN", "OPUS", "ORCA", "OVAL", "OWNER", "PAGE", "PAINT", "PALMA", "PARADE", "PARENT", "PAROLE", "PAUL", "PEACE", "PEARL", "PERFORM", "PHOENIX", "PHRASE", "PIERRE", "PINBALL", "PLACE", "PLATE", "PLATO", "PLUME", "POGO", "POINT", "POLITE", "POLKA", "PONCHO", "POWDER", "PRAGUE", "PRESS", "PRESTO", "PRETTY", "PRIME", "PROMO", "QUASI", "QUEST", "QUICK", "QUIZ", "QUOTA", "RACE", "RACHEL", "RAJA", "RANGER", "REGION", "REMARK", "RENT", "REWARD", "RHINO", "RIBBON", "RIDER", "ROAD", "RODENT", "ROUND", "RUBBER", "RUBY", "RUFUS", "SABINE", "SADDLE", "SAILOR", "SAINT", "SALT", "SATIRE", "SCALE", "SCUBA", "SEASON", "SECURE", "SHAKE", "SHALLOW", "SHANNON", "SHAVE", "SHELF", "SHERMAN", "SHINE", "SHIRT", "SIDE", "SINATRA", "SINCERE", "SIZE", "SLALOM", "SLOW", "SMALL", "SNOW", "SOFIA", "SONG", "SOUND", "SOUTH", "SPEECH", "SPELL", "SPEND", "SPOON", "STAGE", "STAMP", "STAND", "STATE", "STELLA", "STICK", "STING", "STOCK", "STORE", "SUNDAY", "SUNSET", "SUPPORT", "SWEDEN", "SWING", "TAPE", "THINK", "THOMAS", "TICTAC", "TIME", "TOAST", "TOBACCO", "TONIGHT", "TORCH", "TORSO", "TOUCH", "TOYOTA", "TRADE", "TRIBUNE", "TRINITY", "TRITON", "TRUCK", "TRUST", "TYPE", "UNDER", "UNIT", "URBAN", "URGENT", "USER", "VALUE", "VENDOR", "VENICE", "VERONA", "VIBRATE", "VIRGO", "VISIBLE", "VISTA", "VITAL", "VOICE", "VORTEX", "WAITER", "WATCH", "WAVE", "WEATHER", "WEDDING", "WHEEL", "WHISKEY", "WISDOM", "DEAL", "NULL", "NURSE", "QUEBEC", "RESERVE", "REUNION", "ROOF", "SINGER", "VERBAL", "AMEN" }; /* ** Special string comparator. */ static int strspecialcmp(const char* s1, const char* s2) { int c1, c2; do { c1 = toupper(*s1++); c2 = toupper(*s2++); if ((c1 == ' ') || (c1 == '-') || (c1 == '_')) c1 = 0; if ((c2 == ' ') || (c2 == '-') || (c2 == '_')) c2 = 0; if (!c1 || !c2) break; } while (c1 == c2); return c1 - c2; } /* ** Look up a word in the base dictionary and return its index; -1 if the word ** is not in the dictionary. */ static int baseword_to_index(const char* word) { int i; for (i=0; i> (buflen-CHUNK_SIZE)) & ((1<= 4) { value = (buffer >> (buflen-4)) & 0xf; buflen -= 4; blob_appendf(xBlob, "%x", value); } } return 1; } /* ** Implementation of the "mnemonic_encode(X)" SQL function. The argument X ** is an artifact ID prefix (hex characters). It will be mnemonic encoded ** and returned as a string. */ static void sqlcmd_mnemonic_encode( sqlite3_context *context, int argc, sqlite3_value **argv ){ Blob x; const char *zName; int rc; assert( argc==1 ); zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; blob_zero(&x); rc = mnemonic_encode(zName, &x); if ((rc==0) || (blob_size(&x) == 0)) sqlite3_result_error(context, "could not mnemonic encode value", -1); else sqlite3_result_text(context, blob_buffer(&x), blob_size(&x), SQLITE_TRANSIENT); blob_reset(&x); } /* ** Implementation of the "mnemonic_decode(X)" SQL function. The argument X ** is an mnemonic encoded artifact ID prefix (a string of words). It will be ** decoded and returned as a string of hex characters. ** ** If the string is not a valid mnemonic encoded value, it is returned ** unchanged. */ static void sqlcmd_mnemonic_decode( sqlite3_context *context, int argc, sqlite3_value **argv ){ Blob x; const char *zName; int rc; assert( argc==1 ); zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; blob_zero(&x); rc = mnemonic_decode(zName, &x); if ((rc==0) || (blob_size(&x)==0)) sqlite3_result_text(context, zName, -1, SQLITE_TRANSIENT); else sqlite3_result_text(context, blob_buffer(&x), blob_size(&x), SQLITE_TRANSIENT); blob_reset(&x); } /* ** Add the SQL functions that wrap mnemonic_encode() and mnemonic_decode(). */ void mnemonic_add_sql_func(sqlite3 *db) { sqlite3_create_function(db, "mnemonic_encode", 1, SQLITE_ANY, 0, sqlcmd_mnemonic_encode, 0, 0); sqlite3_create_function(db, "mnemonic_decode", 1, SQLITE_ANY, 0, sqlcmd_mnemonic_decode, 0, 0); } /* vi: set ts=2:sw=2:expandtab: */