pwgen.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #!/usr/bin/python
  2. """generate word compound passwords
  3. usage: pwgen -c [number_of_phrases default=1]
  4. or pwgen [len default=20] [number_of_phrases default=1] // no conjunctions
  5. -c use conjunction
  6. """
  7. import random, sys
  8. targetLen = 20 # default pw len
  9. useConjunction = False
  10. number = 1
  11. punc = " !@#$%^&*()-_=+[{]}\|;:/?.>,<`~"
  12. def toInt(s, chkRange, errStr = "sorry, that's not a number", rangeStr = "sorry, I can't do that number"):
  13. try:
  14. t = int(s)
  15. except:
  16. print errStr
  17. sys.exit()
  18. if t<chkRange[0] or t>chkRange[1]:
  19. print rangeStr
  20. sys.exit()
  21. return t
  22. narg = 1
  23. if len(sys.argv)>1:
  24. if sys.argv[1]=="-h" or sys.argv[1]=="--help":
  25. print "pwgen.py v1.2 generate passphrase; inspired by xkcd/936 and SteveGibson\n"
  26. print "Usage: pwgen.py [-p | -P] [length [num_phrases]] "
  27. print " pwgen.py -c [num_phrases]"
  28. print " pwgen.py -h | --help \n"
  29. print " -p pad with only spaces (for smartphone)"
  30. print " -P pad with spaces, period and comma (for smartphone)"
  31. print " length make pass phrases padded with punctuation filler; default=20"
  32. print " -c make 2 word pass phrases with a conjuction filler"
  33. print " num_phrases make multiple pass phrases, one per line; default=1\n"
  34. sys.exit()
  35. elif sys.argv[1]=="-c": # conjunction mode
  36. useConjunction = True
  37. narg = narg + 1
  38. elif sys.argv[1]=="-p": # use only space
  39. punc = " "
  40. narg = narg + 1
  41. elif sys.argv[1]=="-P":
  42. punc = " .,"
  43. narg = narg + 1
  44. if not useConjunction:
  45. if len(sys.argv)>narg:
  46. targetLen = toInt(sys.argv[narg],[12,36],rangeStr = "Sorry, I can't build phrases that long")
  47. narg = narg + 1
  48. if len(sys.argv)>narg:
  49. number = toInt(sys.argv[narg],[0,40]) # pick off the number of phrases
  50. f = open("/usr/share/dict/words")
  51. #f = open("/usr/share/dict/corncob_lowercase.txt")
  52. d = f.read().splitlines()
  53. f.close()
  54. numWords = len(d)
  55. for i in range(number):
  56. w=['','','']
  57. for i in range(3):
  58. w[i] = d[random.randint(0,numWords-1)]
  59. while (len(w[i]) > 10) or (w[i].endswith("'s")):
  60. w[i] = d[random.randint(0,numWords-1)]
  61. whole = len(w[0])+len(w[1])
  62. thisPunct = punc[int(random.random() * len(punc))]
  63. conjunctions = ["and", "and a", "and the","or", "or the", "or a",
  64. "with a", "with", "with the", "by a", "by the",
  65. "on a", "on the","on", "in a", "in the", "in",
  66. "for", "for a", "for the"]
  67. if useConjunction == False:
  68. if whole + 6 >= targetLen: # if 2 words is enough
  69. r = targetLen - whole
  70. pw = w[0] + thisPunct*r + w[1]
  71. else: # otherwise use 3
  72. whole = whole + len(w[2])
  73. r = targetLen - whole
  74. if r<2:
  75. r = 2
  76. pw = w[0] + thisPunct*(r/2) + w[1] + thisPunct*(r-r/2) + w[2]
  77. else:
  78. conj = conjunctions[random.randint(0,len(conjunctions)-1)]
  79. if w[1][0].lower() in ['a','A','e','E','i','I','o','O','u','U']:
  80. if conj[-2:]==" a":
  81. conj = conj+'n'
  82. pw = w[0] + ' ' + conj + ' ' + w[1]
  83. print pw
  84. """
  85. although this
  86. read n; i="1"; while [ $i -le $n ]; do cat /etc/dictionaries-common/words | shuf | head -1; i=$(( $i + 1 )); done
  87. will do the job almost as well
  88. """