|
@@ -11,6 +11,7 @@ import random, sys
|
|
|
targetLen = 20 # default pw len
|
|
|
useConjunction = False
|
|
|
number = 1
|
|
|
+punc = " !@#$%^&*()-_=+[{]}\|;:/?.>,<`~"
|
|
|
|
|
|
def toInt(s, chkRange, errStr = "sorry, that's not a number", rangeStr = "sorry, I can't do that number"):
|
|
|
try:
|
|
@@ -23,25 +24,38 @@ def toInt(s, chkRange, errStr = "sorry, that's not a number", rangeStr = "sorry,
|
|
|
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.0 generate passphrase; inspired by xkcd/936 and SteveGibson\n"
|
|
|
- print "Usage: pwgen.py [length [num_phrases]] "
|
|
|
+ print "pwgen.py v1.2 generate passphrase; inspired by xkcd/936 and SteveGibson\n"
|
|
|
+ print "Usage: pwgen.py [-p | -P] [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 " 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
|
|
|
+ elif 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
|
|
|
+ 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")
|
|
|
-d = f.readlines()
|
|
|
+#f = open("/usr/share/dict/corncob_lowercase.txt")
|
|
|
+d = f.read().splitlines()
|
|
|
f.close()
|
|
|
|
|
|
numWords = len(d)
|
|
@@ -50,13 +64,12 @@ 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
|
|
|
+ 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])
|
|
|
|
|
|
- punc = " !@#$%^&*()-_=+[{]}\|;:/?.>,<`~"
|
|
|
thisPunct = punc[int(random.random() * len(punc))]
|
|
|
|
|
|
conjunctions = ["and", "and a", "and the","or", "or the", "or a",
|
|
@@ -65,13 +78,15 @@ for i in range(number):
|
|
|
"for", "for a", "for the"]
|
|
|
|
|
|
if useConjunction == False:
|
|
|
- if whole >= targetLen - 6: # if 2 words is enough
|
|
|
+ if whole + 6 >= targetLen: # 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]
|
|
|
+ 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']:
|
|
@@ -81,3 +96,12 @@ for i in range(number):
|
|
|
|
|
|
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
|
|
|
+"""
|
|
|
+
|