123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #!/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
- punc = " !@#$%^&*()-_=+[{]}\|;:/?.>,<`~"
- number_punc = "0123456789"
- 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 t<chkRange[0] or t>chkRange[1]:
- print rangeStr
- sys.exit()
- return t
- narg = 1
- if len(sys.argv)>1:
- if sys.argv[1]=="-h" or sys.argv[1]=="--help":
- print "pwgen.py v1.3 generate passphrase; inspired by xkcd/936 and SteveGibson\n"
- print "Usage: pwgen.py [-p | -P | -n | -N] [length [num_phrases]] "
- print " pwgen.py -c [num_phrases]"
- print " pwgen.py -h | --help \n"
- print " -p pad with only spaces (for smartphone)"
- print " -P pad with spaces, period and comma (for smartphone)"
- print " -n pad with numbers"
- print " -N pad with numbers, spaces, period, comma like -P -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()
- elif sys.argv[1]=="-c": # conjunction mode
- useConjunction = True
- narg = narg + 1
- elif sys.argv[1]=='-n': # number fill mode
- punc = number_punc
- narg = narg + 1
- elif sys.argv[1]=='-N':
- punc = number_punc + " ,."
- narg = narg + 1
- elif sys.argv[1]=="-p": # use only space
- punc = " "
- narg = narg + 1
- elif sys.argv[1]=="-P":
- punc = " .,"
- narg = narg + 1
- if not useConjunction:
- if len(sys.argv)>narg:
- targetLen = toInt(sys.argv[narg],[12,36],rangeStr = "Sorry, I can't build phrases that long")
- narg = narg + 1
- if len(sys.argv)>narg:
- number = toInt(sys.argv[narg],[0,40]) # pick off the number of phrases
-
- f = open("/usr/share/dict/words")
- #f = open("/usr/share/dict/corncob_lowercase.txt")
- d = f.read().splitlines()
- f.close()
- numWords = len(d)
- for i in range(number):
- w=['','','']
- for i in range(3):
- w[i] = d[random.randint(0,numWords-1)]
- while (len(w[i]) > 10) or (w[i].endswith("'s")):
- w[i] = d[random.randint(0,numWords-1)]
-
- whole = len(w[0])+len(w[1])
- 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 + 6 >= targetLen: # if 2 words is enough
- r = max(1,targetLen - whole)
- pw = w[0] + thisPunct*r + w[1]
- else: # otherwise use 3
- whole = whole + len(w[2])
- r = targetLen - whole
- if r<2:
- r = 2
- pw = w[0] + thisPunct*(r/2) + w[1] + thisPunct*(r-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
- """
- although this
- read n; i="1"; while [ $i -le $n ]; do cat /etc/dictionaries-common/words | shuf | head -1; i=$(( $i + 1 )); done
- will do the job almost as well
- """
|