Generate passwords which are easy to type
# Generate passwords which can be typed without using any finger to press two | |
# different keys in a row. | |
# For each finger, write the letters *you* type with that finger. | |
finger_classes = [ | |
'qaz', | |
'wsx', | |
'edc', | |
'rfvtgbc', | |
'yhnujmb', | |
'ik', | |
'olp', | |
'p', | |
] | |
def word_filter(x): | |
# Remove overly short words | |
if len(x) < 4: return False | |
# Remove words which aren't lowercase alphabetic | |
allowed_chars = list(chr(i) for i in range(ord('a'), ord('z') + 1)) | |
if any(c not in allowed_chars for c in x): return False | |
# Remove duplicated key presses | |
for i in range(1, len(x)): | |
for cls in finger_classes: | |
if x[i] in cls: | |
if x[i-1] != x[i] and x[i-1] in cls: | |
return False | |
return True | |
def good_words(word_list): | |
order = lambda x: (-len(x), x) | |
return sorted(filter(word_filter, word_list), key=order) | |
def needed_words(num_words, required_bits): | |
from math import log, ceil | |
return ceil(required_bits / log(num_words, 2)) | |
def entropy(n): | |
from math import log | |
return log(n) | |
def genpwd(words, n = 4): | |
from random import randrange | |
return ' '.join(words[randrange(len(words))] for _ in range(n)) | |
def main(): | |
with open('/usr/share/dict/words') as f: | |
word_list = f.read().split() | |
words = good_words(word_list) | |
print("{} usable words found".format(len(words))) | |
print("Four word passphrases give {:0.2f} bits of entropy".format( | |
entropy(len(words) ** 4))) | |
print("Passphrases need {} words for {} bits of entropy".format( | |
needed_words(len(words), 64), 64)) | |
print() | |
for _ in range(16): | |
print(genpwd(words, 4)) | |
if __name__ == '__main__': | |
main() | |
""" | |
35078 usable words found | |
Four word passphrases give 41.86 bits of entropy | |
Passphrases need 5 words for 64 bits of entropy | |
inconspicuous tawniest tasting obsessions | |
peristyles weigh mouthier weepie | |
cinch vigorous veterinaries pricy | |
suckers taskmaster rejigs anemometer | |
negligee hotshots joists disesteem | |
fuzzes styptic angelfish layabout | |
housewifely salves stuffings beltways | |
jobs ayah alliteration coverups | |
vampire super arose pinnacle | |
charabanc biracial reproachful nominee | |
lineups championship canes clauses | |
vigils ladyship internalises automobile | |
spirally drippy sawyers gouge | |
valeting soapsuds fleeter roomette | |
contouring islets odalisques tier | |
quarrellers proton tonsils mayors | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment