#!/usr/bin/python """generate word compound passwords usage: pwgen -c [number_of_phrases default=1] or pwgen [len default=20] [number_of_phrases default=1] // no conjunctions -c use conjunction """ import random, sys targetLen = 20 # default pw len useConjunction = False number = 1 def toInt(s, chkRange, errStr = "sorry, that's not a number", rangeStr = "sorry, I can't do that number"): try: t = int(s) except: print errStr sys.exit() if tchkRange[1]: print rangeStr sys.exit() return t if len(sys.argv)>1: if sys.argv[1]=="-h" or sys.argv[1]=="--help": print "pwgen.py v1.0 generate passphrase; inspired by xkcd/936 and SteveGibson\n" print "Usage: pwgen.py [length [num_phrases]] " print " pwgen.py -c [num_phrases]" print " pwgen.py -h | --help \n" print " length make pass phrases padded with punctuation filler; default=20" print " -c make 2 word pass phrases with a conjuction filler" print " num_phrases make multiple pass phrases, one per line; default=1\n" sys.exit() if sys.argv[1]=="-c": # conjunction mode useConjunction = True else: # the next number is the length targetLen = toInt(sys.argv[1],[12,36],rangeStr = "Sorry, I can't build phrases that long") if len(sys.argv)>2: number = toInt(sys.argv[2],[0,40]) # pick off the number of phrases f = open("/usr/share/dict/words") d = f.readlines() f.close() numWords = len(d) for i in range(number): w=['','',''] for i in range(3): w[i] = d[random.randint(0,numWords-1)][:-1] # toss out trailing \n while len(w[i]) > 10: w[i] = d[random.randint(0,numWords-1)][:-1] # toss out long words whole = len(w[0])+len(w[1]) punc = " !@#$%^&*()-_=+[{]}\|;:/?.>,<`~" thisPunct = punc[int(random.random() * len(punc))] conjunctions = ["and", "and a", "and the","or", "or the", "or a", "with a", "with", "with the", "by a", "by the", "on a", "on the","on", "in a", "in the", "in", "for", "for a", "for the"] if useConjunction == False: if whole >= targetLen - 6: # if 2 words is enough r = targetLen - whole pw = w[0] + thisPunct*r + w[1] else: # otherwise use 3 whole = whole + len(w[2]) r = targetLen - whole pw = w[0] + thisPunct*int(r/2) + w[1] + thisPunct*int(r/2) + w[2] else: conj = conjunctions[random.randint(0,len(conjunctions)-1)] if w[1][0].lower() in ['a','A','e','E','i','I','o','O','u','U']: if conj[-2:]==" a": conj = conj+'n' pw = w[0] + ' ' + conj + ' ' + w[1] print pw