/* ** The word list */ static const char * const azWord[1626] = { "ability", "able", "abroad", "access", "account", "act", "action", "active", "actor", "add", "address", "adept", "adroit", "advance", "advice", "affect", "age", "ageless", "agency", "agent", "agile", "agree", "air", "airfare", "airline", "airport", "alert", "almond", "alpha", "always", "amend", "amount", "amplify", "analyst", "anchor", "angel", "angelic", "angle", "ankle", "annual", "answer", "antique", "anybody", "anyhow", "appeal", "apple", "apricot", "apt", "area", "argon", "arm", "army", "arrival", "arsenic", "art", "artful", "article", "arugula", "aside", "ask", "aspect", "assist", "assume", "atom", "atone", "attempt", "author", "autumn", "average", "avocado", "award", "awl", "azure", "back", "bacon", "bag", "bagel", "bake", "baker", "balance", "ball", "balloon", "bamboo", "banana", "band", "banjo", "bank", "barium", "base", "basil", "basin", "basis", "basket", "bass", "bat", "bath", "battery", "beach", "beak", "bean", "bear", "bearcub", "beauty", "beef", "beet", "beige", "being", "bell", "belly", "belt", "bench", "bend", "benefit", "best", "beta", "better", "beyond", "bicycle", "bid", "big", "bike", "bill", "bird", "biscuit", "bismuth", "bisque", "bit", "black", "blank", "blest", "blind", "bliss", "block", "bloom", "blue", "board", "boat", "body", "bokchoy", "bone", "bonus", "book", "bookish", "boot", "border", "boron", "boss", "bossy", "bottle", "bottom", "bow", "bowl", "bowtie", "box", "brain", "brainy", "branch", "brave", "bravely", "bread", "break", "breath", "breezy", "brick", "bridge", "brie", "brief", "briefly", "bright", "broad", "broil", "bromine", "bronze", "brother", "brow", "brown", "brush", "buddy", "budget", "buffalo", "bug", "bugle", "bull", "bunch", "burger", "burly", "burrito", "bus", "busy", "butter", "button", "buy", "buyer", "byte", "cab", "cabbage", "cabinet", "cable", "cadet", "cadmium", "caesium", "cake", "calcium", "caliper", "call", "caller", "calm", "calmly", "camera", "camp", "can", "canary", "cancel", "candle", "candy", "cap", "capable", "caper", "capital", "captain", "car", "carbon", "card", "care", "career", "careful", "carp", "carpet", "carrot", "carry", "case", "cash", "cassava", "casual", "cat", "catch", "catfish", "catsear", "catsup", "cause", "cave", "celery", "cell", "century", "chain", "chair", "chalk", "chance", "change", "channel", "chapter", "chard", "charge", "charity", "chart", "check", "cheddar", "cheery", "cheese", "chicken", "chicory", "chiffon", "child", "chin", "chip", "chives", "choice", "chowder", "chum", "church", "circle", "city", "claim", "clam", "class", "classic", "classy", "clay", "clean", "cleaner", "clear", "clearly", "clerk", "click", "client", "climate", "clock", "clorine", "closet", "clothes", "cloud", "clown", "club", "clue", "cluster", "coach", "coast", "coat", "cobbler", "cobolt", "cod", "code", "coffee", "colby", "cold", "collar", "college", "comb", "combine", "comet", "comfort", "command", "comment", "common", "company", "complex", "concept", "concern", "concert", "conduit", "consist", "contact", "contest", "context", "control", "convert", "cook", "cookie", "copilot", "copper", "copy", "coral", "cordial", "corn", "corner", "corny", "correct", "cost", "count", "counter", "country", "county", "couple", "courage", "course", "court", "cover", "cow", "cowbird", "crab", "crack", "craft", "crash", "crazy", "cream", "credit", "creek", "cress", "crevice", "crew", "crimson", "croaker", "crop", "cross", "crowd", "cube", "cuckoo", "cuisine", "culture", "cup", "current", "curve", "cut", "cyan", "cycle", "dagger", "daily", "dance", "dare", "darter", "data", "date", "day", "daylily", "deal", "dear", "dearly", "debate", "debit", "decade", "decimal", "deep", "deft", "deftly", "degree", "delay", "deluxe", "deposit", "depth", "design", "desk", "detail", "device", "dew", "diamond", "diet", "dig", "dill", "dinner", "dip", "direct", "dirt", "dish", "disk", "display", "diver", "divide", "divine", "doctor", "dodger", "donut", "door", "dot", "double", "dough", "draft", "drag", "dragon", "drama", "draw", "drawer", "drawing", "dream", "drill", "drink", "drive", "driver", "drop", "drum", "dry", "dryer", "drywall", "duck", "due", "dump", "dusk", "dust", "duty", "dye", "eagle", "ear", "earring", "earth", "ease", "east", "easy", "eat", "economy", "edge", "editor", "eel", "effect", "effort", "egg", "eight", "elbow", "elegant", "element", "elf", "elk", "email", "emerald", "employ", "end", "endive", "endless", "energy", "engine", "enjoy", "enter", "entry", "equal", "equip", "error", "escape", "essay", "eternal", "evening", "event", "exam", "example", "excuse", "exit", "expert", "extent", "extreme", "eye", "face", "fact", "factor", "factual", "fail", "failure", "fair", "fajita", "fall", "family", "fan", "fang", "farm", "farmer", "fat", "fault", "feature", "feed", "feel", "feeling", "fench", "fennel", "festive", "few", "fiber", "field", "fig", "figure", "file", "fill", "film", "filter", "final", "finance", "finding", "finger", "finish", "fire", "fish", "fishing", "fit", "fitting", "five", "fix", "flier", "flight", "floor", "floral", "florine", "flour", "flow", "flower", "fly", "flying", "focus", "fold", "folding", "food", "foot", "force", "forest", "forever", "forgive", "form", "formal", "format", "fortune", "forum", "frame", "free", "freedom", "freely", "fresh", "friend", "frog", "front", "fruit", "fuchsia", "fuel", "fun", "funny", "future", "gain", "galaxy", "gallium", "game", "gamma", "gap", "garage", "garden", "garlic", "gas", "gate", "gather", "gauge", "gear", "gem", "gene", "general", "gentle", "gently", "gherkin", "ghost", "gift", "give", "glad", "glass", "gleeful", "glossy", "glove", "glue", "goal", "goat", "goby", "gold", "goldeye", "golf", "good", "gouda", "goulash", "gourd", "grab", "grace", "grade", "gram", "grand", "grape", "grapes", "grass", "gravy", "gray", "great", "green", "grits", "grocery", "ground", "group", "grouper", "grout", "growth", "guard", "guave", "guess", "guest", "guide", "guitar", "gumbo", "guppy", "habit", "hacksaw", "haddock", "hafnium", "hagfish", "hair", "half", "halibut", "hall", "hammer", "hand", "handle", "handy", "hanger", "happy", "hat", "havarti", "hay", "haybale", "head", "health", "healthy", "hearing", "heart", "hearty", "heat", "heavy", "heel", "height", "helium", "hello", "help", "helpful", "herald", "herring", "hide", "high", "highly", "highway", "hill", "hip", "hipster", "hire", "history", "hit", "hoki", "hold", "hole", "holiday", "holly", "home", "honest", "honey", "hook", "hope", "hopeful", "horizon", "horn", "horse", "host", "hotel", "hour", "house", "housing", "human", "humane", "humor", "hunt", "hurry", "ice", "icecube", "icefish", "icy", "idea", "ideal", "image", "impact", "impress", "inch", "income", "indigo", "initial", "inkpen", "insect", "inside", "intense", "invite", "iodine", "iridium", "iron", "island", "issue", "item", "ivory", "jacket", "jargon", "javelin", "jello", "jelly", "jewel", "job", "jocund", "join", "joint", "joke", "jovial", "joy", "joyful", "joyous", "judge", "juice", "jump", "junior", "jury", "just", "justice", "kale", "keel", "keep", "kelp", "ketchup", "key", "keyhole", "keyway", "khaki", "kick", "kid", "kidney", "kiloohm", "kind", "kindly", "king", "kitchen", "kite", "kiwi", "knee", "knife", "krill", "krypton", "kumquat", "lab", "lace", "lack", "ladder", "lake", "lamp", "lamprey", "land", "laser", "laugh", "law", "lawn", "lawyer", "layer", "lead", "leader", "leading", "leaf", "leafy", "league", "leather", "leave", "lecture", "leek", "leg", "lemon", "length", "lentil", "lesson", "let", "letter", "lettuce", "level", "library", "life", "lift", "light", "lily", "lime", "limit", "line", "linen", "link", "lip", "list", "listen", "lithium", "lively", "living", "lizard", "load", "loan", "lobster", "local", "lock", "log", "long", "longfin", "look", "lotus", "love", "lovely", "loving", "low", "lucid", "luck", "luffa", "lunch", "lung", "machine", "magenta", "magnet", "mail", "main", "major", "make", "mall", "manager", "mango", "manner", "many", "map", "march", "market", "maroon", "martian", "master", "match", "math", "matter", "maximum", "maybe", "meal", "meaning", "meat", "media", "medium", "meet", "meeting", "melody", "melon", "member", "memory", "mention", "menu", "mercury", "merry", "mess", "message", "messy", "metal", "meter", "method", "micron", "middle", "might", "mile", "milk", "mind", "mine", "minimum", "minnow", "minor", "mint", "minute", "mirror", "miss", "mission", "misty", "mix", "mixer", "mixture", "mobile", "mode", "model", "moment", "monitor", "monk", "month", "moon", "moray", "morning", "most", "motor", "mouse", "mouth", "move", "mover", "movie", "much", "mud", "mudfish", "muffin", "mullet", "munster", "muon", "muscle", "music", "mustard", "nail", "name", "nation", "native", "natural", "nature", "navy", "neat", "neatly", "nebula", "neck", "needle", "neon", "nerve", "net", "network", "neutron", "news", "nibble", "nice", "nickel", "night", "niobium", "nobody", "noise", "noodle", "normal", "north", "nose", "note", "nothing", "notice", "nova", "novel", "number", "nurse", "nursery", "oar", "object", "offer", "office", "officer", "oil", "okay", "okra", "old", "olive", "one", "onion", "open", "opening", "opinion", "option", "orange", "orbit", "orchid", "order", "oregano", "other", "ounce", "outcome", "outside", "oven", "owner", "oxygen", "oyster", "pace", "pack", "package", "page", "pager", "paint", "pair", "pale", "pan", "pancake", "papaya", "paper", "pardon", "parent", "park", "parking", "parsley", "parsnip", "part", "partner", "party", "pass", "passage", "past", "pasta", "path", "patient", "pattern", "pause", "pay", "pea", "peace", "peach", "peacock", "peahen", "peak", "peanut", "pear", "pearl", "pen", "penalty", "pencil", "pension", "people", "pepper", "perch", "perfect", "period", "permit", "person", "phase", "phone", "photo", "phrase", "physics", "piano", "pick", "picture", "pie", "piece", "pigeon", "pike", "pilot", "pin", "pink", "pinkie", "pious", "pipe", "pitch", "pizza", "place", "plan", "plane", "planet", "plant", "planter", "plastic", "plate", "play", "player", "playful", "plenty", "pliers", "plum", "pod", "poem", "poet", "poetry", "point", "police", "policy", "pollock", "pony", "pool", "pop", "popover", "poptart", "pork", "port", "portal", "post", "pot", "potato", "pound", "powder", "power", "present", "press", "price", "pride", "primary", "print", "prior", "private", "prize", "problem", "process", "produce", "product", "profile", "profit", "program", "project", "promise", "prompt", "proof", "proper", "protein", "proton", "public", "puff", "puffer", "pull", "pumpkin", "pup", "pupfish", "pure", "purple", "purpose", "push", "put", "quality", "quark", "quarter", "quiet", "quill", "quit", "quote", "rabbit", "raccoon", "race", "radiant", "radio", "radish", "radium", "radon", "rain", "rainbow", "raise", "ramp", "ranch", "range", "rasp", "rate", "ratio", "ray", "razor", "reach", "read", "reading", "real", "reality", "reason", "recipe", "record", "recover", "red", "redeem", "reed", "reef", "refuse", "region", "regret", "regular", "relaxed", "release", "relief", "relish", "remote", "remove", "rent", "repair", "repeat", "reply", "report", "request", "reserve", "resist", "resolve", "resort", "rest", "result", "return", "reveal", "review", "reward", "ribbon", "rice", "rich", "ride", "ridge", "right", "ring", "rise", "risk", "river", "rivet", "road", "roast", "rock", "rocket", "role", "roll", "roof", "room", "rope", "rose", "rough", "roughy", "round", "row", "royal", "rub", "ruby", "rudder", "ruin", "rule", "run", "runner", "rush", "rust", "sacred", "saddle", "safe", "safety", "sail", "salad", "salami", "sale", "salmon", "salt", "sample", "sand", "sander", "sandy", "sauce", "save", "saving", "saw", "scale", "scampi", "scene", "scheme", "school", "score", "screen", "script", "sea", "search", "season", "seat", "second", "secret", "sector", "seemly", "self", "sell", "senate", "senior", "sense", "series", "serve", "set", "shake", "shape", "share", "shark", "shell", "shift", "shine", "shiny", "ship", "shock", "shoe", "shoot", "shop", "shovel", "show", "side", "sign", "signal", "silk", "silly", "silver", "simple", "sing", "singer", "single", "sink", "site", "size", "skill", "skin", "sky", "slate", "sleep", "sleepy", "slice", "slide", "slip", "smart", "smell", "smelt", "smile", "smoke", "smooth", "snap", "snipe", "snow", "snowy", "sock", "socket", "sodium", "soft", "softly", "soil", "sole", "solid", "song", "sorrel", "sort", "soul", "sound", "soup", "source", "south", "space", "spare", "speech", "speed", "spell", "spend", "sphere", "spice", "spider", "spirit", "spite", "split", "spoon", "sport", "spot", "spray", "spread", "spring", "squab", "square", "squash", "stable", "staff", "stage", "stand", "staple", "star", "start", "state", "status", "stay", "steak", "steel", "step", "stern", "stew", "stick", "still", "stock", "stone", "stop", "store", "storm", "story", "strain", "street", "stress", "strike", "string", "stroke", "strong", "studio", "study", "stuff", "style", "sugar", "suit", "sulfur", "summer", "sun", "sunny", "sunset", "super", "superb", "surf", "survey", "sweet", "swim", "swing", "switch", "symbol", "system", "table", "tackle", "tail", "tale", "talk", "tan", "tank", "tap", "tape", "target", "task", "taste", "tau", "tea", "teach", "teal", "team", "tear", "tell", "ten", "tender", "tennis", "tent", "term", "test", "tetra", "text", "thanks", "theme", "theory", "thing", "think", "thread", "throat", "thumb", "ticket", "tidy", "tie", "tiger", "till", "time", "timely", "tin", "tip", "title", "toast", "today", "toe", "tomato", "tone", "tongue", "tool", "tooth", "top", "topic", "total", "touch", "tough", "tour", "towel", "tower", "town", "track", "trade", "train", "trash", "travel", "tray", "treat", "tree", "trick", "trip", "trout", "trowel", "truck", "trupet", "trust", "truth", "try", "tube", "tuna", "tune", "turf", "turkey", "turn", "turnip", "tutor", "tux", "tweet", "twist", "two", "type", "union", "unique", "unit", "upbeat", "upper", "use", "useful", "user", "usual", "valley", "value", "van", "vase", "vast", "veil", "vein", "velvet", "verse", "very", "vessel", "vest", "video", "view", "violet", "visit", "visual", "vivid", "voice", "volume", "vowel", "voyage", "waffle", "wait", "wake", "walk", "wall", "warm", "warmth", "wasabi", "wash", "watch", "water", "wave", "wax", "way", "wealth", "wear", "web", "wedge", "week", "weekly", "weight", "west", "whale", "what", "wheat", "wheel", "when", "where", "while", "who", "whole", "why", "will", "win", "wind", "window", "wing", "winner", "winter", "wire", "wish", "witty", "wolf", "wonder", "wood", "wool", "woolly", "word", "work", "worker", "world", "worry", "worth", "worthy", "wrap", "wrench", "wrist", "writer", "xenon", "yak", "yam", "yard", "yarrow", "year", "yearly", "yellow", "yew", "yogurt", "young", "youth", "zebra", "zephyr", "zinc", "zone", "zoo", }; /* ** Output a selection of random word strings. */ #include #include #include #include #include #include #include /* ** Open the input file named in the argument. If it looks like a ** CGI script that invoked this binary, then output the text of that ** script (eliding lines beginning with #) until the first line of %% ** is seen, then return the input FILE. If the input cannot be opened ** then just return NULL. */ static FILE *startCgi(const char *zFile){ FILE *in = fopen(zFile, "rb"); char zLine[1000]; if( in==0 ) return 0; while( fgets(zLine, sizeof(zLine), in) ){ if( zLine[0]=='#' ) continue; if( zLine[0]=='%' && zLine[1]=='%' ) return in; fputs(zLine, stdout); } fclose(in); return 0; } /* ** Finish copying FILE to stdout. */ static void finishCgi(FILE *in){ char zLine[1000]; if( in==0 ) return; while( fgets(zLine, sizeof(zLine), in) ){ if( zLine[0]=='#' ) continue; fputs(zLine, stdout); } fclose(in); } /* Render 42 bits of integer v as a 7-digit base-64 number. */ const char *base64(unsigned long long int v){ const char zDigits[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/-"; /* 123456789 123456789 123456789 123456789 123456789 123456789 1234 */ static char zVal[10]; int i; zVal[7] = 0; for(i=6; i>=0; i--){ zVal[i] = zDigits[v&0x3f]; v >>= 6; } return zVal; } /* Render 42 bits of integer v as a 8-character text encoding that ** avoids potentially ambiguous characters like "l", "1", "0", and "O". */ const char *safeEncode(unsigned long long int v){ const char zDigits[] = "23456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"; /* 123456789 123456789 123456789 123456789 123456789 123456789 1234 */ static char zVal[10]; int i; zVal[8] = 0; for(i=0; i<8; i++){ zVal[i] = zDigits[v%57]; v /= 57; } return zVal; } /* Return a random permutation of characters, omitting easily confused ** characters "l", "1", "0", and "O". The resulting 11-character string ** has about 62.6 bits of entropy. */ const char *permutedText(unsigned long long int v){ char zDigits[60]; unsigned int nDigit; int i; static char zVal[16]; /* 123456789 123456789 123456789 123456789 123456789 1234567 */ strcpy(zDigits,"23456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"); nDigit = 57; for(i=0; i<11; i++){ unsigned int n = v%nDigit; v /= nDigit; zVal[i] = zDigits[n]; nDigit--; zDigits[n] = zDigits[nDigit]; } zVal[i] = 0; return zVal; } /* Similar, but with two random 64-bit numbers as input, yielding a ** 22-character output string with approximately 121 bits of entropy. */ const char *permutedText2(unsigned long long int v, unsigned long long int v2){ char zDigits[60]; unsigned int nDigit; int i; static char zVal[24]; /* 123456789 123456789 123456789 123456789 123456789 1234567 */ strcpy(zDigits,"23456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"); nDigit = 57; for(i=0; i<11; i++){ unsigned int n = v%nDigit; v /= nDigit; zVal[i] = zDigits[n]; nDigit--; zDigits[n] = zDigits[nDigit]; } for(i=11; i<22; i++){ unsigned int n = v2%nDigit; v2 /= nDigit; zVal[i] = zDigits[n]; nDigit--; zDigits[n] = zDigits[nDigit]; } zVal[i] = 0; return zVal; } /* Given two random 64-bit numbers as input, generate a password that ** is relatively easy to type. */ unsigned char *easyToType( unsigned long long int v, unsigned long long int u, unsigned char *z ){ unsigned int n = 0; int i; int nFore; z[n++] = 'A' + (v%26); v /= 26; nFore = v%9; v /= 9; for(i=0; i1 ? startCgi(argv[1]) : 0; fd = open("/dev/urandom", O_RDONLY); if( fd<0 ){ fprintf(stderr, "Cannot open /dev/urandom\n"); exit(1); } for(i=0; i<4; i++){ read(fd, &x, sizeof(x)); xx = x; x &= (((unsigned long long int)1)<<42)-1; y = x; a1 = x%1626; x = x/1626; a2 = x%1626; x /= 1626; a3 = x%1626; x /= 1626; a4 = x%1626; printf("%011llx %013llu %s %s %s-%s-%s-%s\n", y, y, base64(y), safeEncode(xx), azWord[a1], azWord[a2], azWord[a3], azWord[a4]); } for(i=0; i<4; i++){ read(fd, &x, sizeof(x)); printf("%016llx %020llu %s\n", x, x, permutedText(x)); } for(i=0; i<3; i++){ read(fd, &x, sizeof(x)); read(fd, &y, sizeof(y)); printf("%016llx%016llx %s\n", x, y, permutedText2(x,y)); } for(i=0; i<3; i++){ read(fd, &x, sizeof(x)); read(fd, &y, sizeof(x)); printf("%016llx%016llx %s\n", x, y, easyToType(x,y,z)); } #if 0 for(i=0; i<3; i++){ int j; read(fd, z, 60); z[60] = 0; for(j=0; j<60; j+=2){ z[j] = (z[j]%26)+'a'; z[j+1] = (z[j+1]%10)+'0'; } printf("%.10s %.10s %.10s %.10s %.10s %.10s\n", z, z+10, z+20, z+30, z+40, z+50); } #endif close(fd); finishCgi(pScript); return 0; }