Skip to content

Instantly share code, notes, and snippets.

@MagerValp
Created October 2, 2012 17:03
Show Gist options
  • Save MagerValp/3821185 to your computer and use it in GitHub Desktop.
Save MagerValp/3821185 to your computer and use it in GitHub Desktop.
Generate memorable passwords
#!/usr/bin/python
import sys
import optparse
import random
rndgen = random.SystemRandom()
words = list(s.rstrip() for s in open("/usr/share/dict/words"))
punctuation = "!\"#&'()*,-./:;?@[\\]_{}"
digits = "0123456789"
def gen_memorable_pwd(pwd_len):
"""Generate passwords with an algorithm similar to the Password
Assistant's 'memorable' kind - two random words with a random number
and punctuation between."""
global rndgen
global words
global punctuation
global digits
while True:
# Grab two random words.
word1, word2 = rndgen.sample(words, 2)
# Make sure that they aren't so long that we can't fit a random number
# and punctuation inbetween, and not too short so we need more than 9
# digits.
sum_len = len(word1) + len(word2)
max_word_len = pwd_len - 2
min_word_len = pwd_len - 11
if sum_len > max_word_len or sum_len < min_word_len:
continue
# Generate a random number to pad the password.
rand_num_list = rndgen.sample(digits, pwd_len - sum_len- 1)
# Convert the list of numbers to a string.
rand_num = "".join(str(n) for n in rand_num_list)
# Join the parts with random punctuation.
return "%s%s%s%s" % (
word1,
rand_num,
rndgen.sample(punctuation, 1)[0],
word2,
)
def gen_xkcd_pwd(num_words):
"""Pick random words, e.g. 'correct horse battery staple'."""
global rndgen
global words
return " ".join(rndgen.sample(words, num_words))
def main(argv):
p = optparse.OptionParser()
p.set_usage("""Usage: %prog [options]""")
p.add_option("-l", "--length", type=int, dest="length",
help="Password length.")
p.add_option("-c", "--count", type=int, dest="count", default=10,
help="Number of passwords to generate.")
p.add_option("-x", "--xkcd", action="store_true", dest="xkcd",
help="Use xkcd algorithm instead.")
options, argv = p.parse_args(argv)
if len(argv) != 1:
print >>sys.stderr, p.get_usage()
return 1
if options.xkcd:
pwd_func = gen_xkcd_pwd
default_len = 4
if options.length is not None and options.length < 2:
sys.exit("Too short!")
else:
pwd_func = gen_memorable_pwd
default_len = 12
if options.length is not None and options.length < 8:
sys.exit("Too short!")
elif options.length is not None and options.length > 31:
sys.exit("Too long!")
for i in range(options.count):
print pwd_func(options.length or default_len)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment