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