annotate ppgen.py @ 3:757625ec8364

Comment added hint about SLT's Go implementation.
author Bernhard Reiter <bernhard@intevation.de>
date Mon, 02 May 2016 09:26:29 +0200
parents a099246680ae
children 85c65a597420
rev   line source
0
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
1 #!/usr/bin/env python3
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
2 """Create a passphrase from a few random words. DRAFT
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
3
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
4 Relies on the entropy of python's
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
5 random.SystemRandom class
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
6 which (according to the documentation) calls os.urandom()
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
7 which (according to the documentation) calls the operating system
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
8 specific randomness source which "should be unpredictable
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
9 enough for cryptographic applications"
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
10
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
11 Requires:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
12 * Python v>=3.2
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
13 * a dictionary, Ding's trans-de-en by default.
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
14 E.g. on a Debian/Ubuntu system in package "trans-de-en".
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
15 or from http://ftp.tu-chemnitz.de/pub/Local/urz/ding/de-en/
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
16
1
00ed7df30fe4 Checking for 8k entries now. Comment improvements.
Bernhard Reiter <bernhard@intevation.de>
parents: 0
diff changeset
17 Uses a hardcoded filepath and language.
0
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
18 Search for **customize** below to change it.
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
19
3
757625ec8364 Comment added hint about SLT's Go implementation.
Bernhard Reiter <bernhard@intevation.de>
parents: 2
diff changeset
20 Related: There is a Go implementation started by Sascha L. Teichmann at
757625ec8364 Comment added hint about SLT's Go implementation.
Bernhard Reiter <bernhard@intevation.de>
parents: 2
diff changeset
21 https://bitbucket.org/s_l_teichmann/ppgen
757625ec8364 Comment added hint about SLT's Go implementation.
Bernhard Reiter <bernhard@intevation.de>
parents: 2
diff changeset
22
757625ec8364 Comment added hint about SLT's Go implementation.
Bernhard Reiter <bernhard@intevation.de>
parents: 2
diff changeset
23
0
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
24 Copyright 2016 by Intevation GmbH.
1
00ed7df30fe4 Checking for 8k entries now. Comment improvements.
Bernhard Reiter <bernhard@intevation.de>
parents: 0
diff changeset
25 Author: Bernhard E. Reiter <bernhard@intevation.de>
0
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
26
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
27 This file is Free Software under the Apache 2.0 license and thus
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
28 comes without any warranty (to extend permissible under applicable law).
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
29 """
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
30
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
31 import math
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
32 import re
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
33 import sys
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
34
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
35 from random import SystemRandom
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
36 _srandom = SystemRandom()
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
37
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
38 tainted = False # to be set if we find a hint that the passphrase may be weak
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
39
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
40 def buildDictionary():
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
41 """Build up a dictionary of unique words, calculate stats."""
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
42 global tainted
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
43 d = []
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
44
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
45 # dictionary for testing
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
46 #d = ["abc", "aBc", "cde", "efg", "hij", "blubber", "jikf", "zug", "lmf", "opq"]
2
a099246680ae Fix for the unique test.
Bernhard Reiter <bernhard@intevation.de>
parents: 1
diff changeset
47 # second test dictionary to show that different string functions are used.
a099246680ae Fix for the unique test.
Bernhard Reiter <bernhard@intevation.de>
parents: 1
diff changeset
48 #d = [''.join('A' * 1000) for _ in range(1000)]
0
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
49
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
50 # Using the dictionary from Ding **customize**
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
51 d = readDingDict(filename="/usr/share/trans/de-en", useLeft=True)
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
52
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
53 ## for debugging purpuses, dump dictionary
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
54 #dumpfilename = "ddump.txt"
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
55 #print("Writing out {}.".format(dumpfilename))
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
56 #with open(dumpfilename, "w") as f:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
57 # for i in d:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
58 # f.write("{}\n".format(i))
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
59
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
60 # Print some stats on the dictionary to be used
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
61 dl = len(d)
1
00ed7df30fe4 Checking for 8k entries now. Comment improvements.
Bernhard Reiter <bernhard@intevation.de>
parents: 0
diff changeset
62 print("Found {:d} dictionary entries.".format(dl))
00ed7df30fe4 Checking for 8k entries now. Comment improvements.
Bernhard Reiter <bernhard@intevation.de>
parents: 0
diff changeset
63 if dl < 8000:
00ed7df30fe4 Checking for 8k entries now. Comment improvements.
Bernhard Reiter <bernhard@intevation.de>
parents: 0
diff changeset
64 print("!Your dictionary is below 8k entries, that is quite small!")
0
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
65 tainted = True
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
66
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
67 print("|= Number of words |= possibilities |")
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
68 for i in range(1,5):
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
69 print("| {:2d} | 2^{:4.1f} |".format(
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
70 i, math.log(dl**i,2)))
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
71 return d
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
72
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
73
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
74 def readDingDict(filename = "/usr/share/trans/de-en", useLeft=False):
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
75 """Read dictionary with unique words from file in Ding format.
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
76
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
77 useLeft: Boolean to control which language to use
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
78
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
79 TODO: add option to use both languages for people that speak them both?
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
80 """
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
81
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
82 dset = set() #using the datatype 'set' to aviod duplicates
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
83
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
84 splitter = re.compile(r"""\ \|\ # first pattern ' | '
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
85 |;\ # second pattern '; '
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
86 |(?<=\S)/(?=\S) # 3.: '\' surrounded by chars
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
87 |\s+ # by whitespace
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
88 """,re.VERBOSE)
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
89
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
90 print("Reading entries from {}.".format(filename), end='')
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
91 counter = 0 # for progress or stopping early
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
92 with open(filename, "r") as f:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
93 for line in f:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
94 if line[0] == '#': continue
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
95
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
96 # languages are separated by " :: "
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
97 p = line.partition(" :: ")
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
98 languageEntry = p[0] if useLeft else p[2]
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
99
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
100 for word in splitter.split(languageEntry):
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
101 word = word.strip('(",.)\'!:;').rstrip('/')
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
102 if len(word) > 2 and not word[0] in '[{/':
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
103 dset.add(word)
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
104
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
105 #TODO: check for very common words and remove them?
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
106
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
107 counter += 1
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
108 ## stop early when debugging
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
109 #if counter > 10: break
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
110 if not counter % 10000:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
111 print('.', end='')
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
112 sys.stdout.flush()
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
113 print()
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
114
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
115 return list(dset)
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
116
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
117 def main():
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
118 global tainted
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
119 dictionary = buildDictionary()
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
120
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
121 howMany = 4
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
122
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
123 # use a dictionary with lower case words for a simple check if
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
124 # our random source is okay
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
125 print("\nGenerated passphrase with {} randomly selected words:\n".format(
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
126 howMany))
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
127 print(" ", end='')
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
128 words = {}
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
129 for x in range(howMany):
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
130 word = _srandom.choice(dictionary)
2
a099246680ae Fix for the unique test.
Bernhard Reiter <bernhard@intevation.de>
parents: 1
diff changeset
131 words[word.lower()]= True
0
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
132 print(word, end='\n ')
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
133 print("\n")
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
134
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
135 if len(words) < howMany:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
136 print("! Your random generator is weak")
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
137 print("! or you are being very lucky.")
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
138 tainted = True
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
139
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
140 if tainted:
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
141 print("!!! Don't use the resulting passphrase !!!")
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
142
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
143 if __name__ == "__main__":
7558ecd1cbf1 Initial version.
Bernhard Reiter <bernhard@intevation.de>
parents:
diff changeset
144 main()
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)