Enhanced xkcd password generator

gpw and xkcdpass have entered testing.

How about putting them together?


import subprocess
import random
import re

re_spaces = re.compile(r"\s+")

def get_words(cmd):
    out = subprocess.check_output(cmd, universal_newlines=True)
    return (x for x in re_spaces.split(out) if x)

words = set()

words.update(get_words(["xkcdpass", "-c", "10"]))

for l in range(6, 9):
    words.update(get_words(["gpw", "10", str(l)]))

for i in range(7):
    print(" ".join(random.sample(words, 5)))

Let's check the results:


from __future__ import print_function
from zxcvbn import password_strength
import sys

for line in sys.stdin:
    pw = line.strip()
    info = password_strength(pw)
    print("{pw}: {crack_time_display} {entropy}".format(pw=pw, **info))
$ xkcdpass -n 5 -c 7 | ./checkpass
moribund fasten cologne enamor by-and-by: centuries 132.586
woolen leptonic pogrom roster Serra: centuries 127.145
shorthand Piman suctional elution unholy: centuries 119.809
Blackwell mauvish covey selenium finished: centuries 112.936
asthma bloat crenulate clean-cut cytoplasm: centuries 150.181
agreeable refined racism Captain Cyrenaic: centuries 104.28
Bothnia stagnant atomist these revise: centuries 97.91
$ gpw 7 | ./checkpass
ncenspri: 11.0 days 33.903
orsterma: instant 19.54
entsssel: 14.0 hours 29.788
tempispi: instant 20.058
nidgersi: 14.0 hours 29.725
oligalin: 51.0 minutes 25.824
iseartio: 10.0 minutes 23.207
$ ./metapass | ./checkpass
herups icirop overdub oldster cingsape: centuries 147.265
mujahidin usufruct rition porky prignam: centuries 153.684
cannula irenics tableaux ntshed calcific: centuries 152.196
stopgap stale orthente Amazonia sharer: centuries 113.474
edudives mmingsso eremab prignam tableaux: centuries 147.354
tingei heroism Nathaniel cannula molasses: centuries 103.007
Torres blood lewdness prignam eremab: centuries 118.475

The strength, according to zxcvbn, seems only marginally better, and it's a wonderful way to grow a vocabulary of nonexisting words that can be dropped into cheap talk conversation to confuse the innocents.