Переглянути джерело

version 1.2 stable and useful

Pat Beirne 8 роки тому
батько
коміт
1acd2e16ec
1 змінених файлів з 38 додано та 14 видалено
  1. 38 14
      pwgen.py

+ 38 - 14
pwgen.py

@@ -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
+"""
+