changeset 8:200c2c3c5f67

Adds comfort. * Adds options ** '--just-passphrase': to get a passphrase on one line for use in skripts. ** '--number-of-words': the passphrase shall consists of * Refactors to implement the options and preparing for future developments: ** Warnings will be written to stderr and tained will bail out with sys.exit(). ** The output_string is build before printing.
author Bernhard Reiter <bernhard@intevation.de>
date Thu, 18 Jan 2018 08:44:33 +0100
parents 8b2f8f439817
children 35c468a37b54
files ppgen.py
diffstat 1 files changed, 46 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/ppgen.py	Tue Feb 21 14:14:08 2017 +0100
+++ b/ppgen.py	Thu Jan 18 08:44:33 2018 +0100
@@ -21,7 +21,7 @@
   https://bitbucket.org/s_l_teichmann/ppgen
 
 
-Copyright 2016, 2017 by Intevation GmbH.
+Copyright 2016, 2017, 2018 by Intevation GmbH.
 Author: Bernhard E. Reiter <bernhard@intevation.de>
 
 This file is Free Software under the Apache 2.0 license and thus
@@ -51,9 +51,9 @@
     #d =  [''.join('A' * 1000) for _ in range(1000)]
 
     # Using the dictionary from Ding **customize**
-    d = readDingDict(filename="/usr/share/trans/de-en", useLeft=True)
+    d = readDingDict(options, filename="/usr/share/trans/de-en", useLeft=True)
 
-    ## for debugging purposes, dump dictionary
+    # for debugging purposes, dump dictionary
     if options.ddump_filename:
         print("Writing out dictionary in '{}'.".format(options.ddump_filename))
         with open(options.ddump_filename, "w") as f:
@@ -62,19 +62,21 @@
 
     # Print some stats on the dictionary to be used
     dl = len(d)
-    print("Found {:d} dictionary entries.".format(dl))
+    if not options.just_passphrase:
+        print("Found {:d} dictionary entries.".format(dl))
+        print("|= Number of words |= possibilities |")
+        for i in range(1, 5):
+            print("|               {:2d} |    2^{:4.1f}      |".format(
+                  i, math.log(dl**i, 2)))
+
     if dl < 8000:
-        print("!Your dictionary is below 8k entries, that is quite small!")
+        sys.stderr.write("!Your dictionary is below 8k entries, "
+                         "that is quite small!\n")
         tainted = True
-
-    print("|= Number of words |= possibilities |")
-    for i in range(1, 5):
-        print("|               {:2d} |    2^{:4.1f}      |".format(
-              i, math.log(dl**i, 2)))
     return d
 
 
-def readDingDict(filename="/usr/share/trans/de-en", useLeft=False):
+def readDingDict(options, filename="/usr/share/trans/de-en", useLeft=False):
     """Read dictionary with unique words from file in Ding format.
 
     useLeft: Boolean to control which language to use
@@ -90,7 +92,8 @@
                            |\s+      # by whitespace
                            """, re.VERBOSE)
 
-    print("Reading entries from {}.".format(filename), end='')
+    if not options.just_passphrase:
+        print("Reading entries from {}.".format(filename), end='')
     counter = 0  # for progress or stopping early
     with open(filename, "r") as f:
         for line in f:
@@ -111,10 +114,11 @@
             counter += 1
             ## stop early when debugging
             #if counter > 10: break
-            if not counter % 10000:
+            if not options.just_passphrase and counter % 10000 == 0:
                     print('.', end='')
                     sys.stdout.flush()
-        print()
+        if not options.just_passphrase:
+            print()
 
     return list(dset)
 
@@ -122,34 +126,48 @@
 def main():
     global tainted
 
-    parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
+    parser = argparse.ArgumentParser(
+        description=__doc__.splitlines()[0],
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+    parser.add_argument('-n', '--number-of-words', type=int, default=4,
+                        help='how many words to draw for the passphrase, '
+                             'most useful with -j')
+    parser.add_argument('-j', '--just-passphrase', action="store_true",
+                        help='only output the passphrase on a single line')
     parser.add_argument('--ddump-filename',
                         help='filename to dump the dictionary to')
     options = parser.parse_args()
 
     dictionary = buildDictionary(options)
 
-    howMany = 4
+    how_many = options.number_of_words
 
-    # use a dictionary with lower cased words for a simple check if
-    # our random source is okay
-    print("\nGenerated passphrase with {} randomly selected words:\n".format(
-          howMany))
-    print("    ", end='')
+    output_string = ""
+    if not options.just_passphrase:
+        print("\nGenerated passphrase with {}"
+              " randomly selected words:\n".format(how_many))
+        print("    ", end='')
+        separator = '\n    '
+    else:
+        separator = ' '
+
+    # use a dictionary `words` with lower cased words for a rudimentary check
     words = {}
-    for x in range(howMany):
+    for x in range(how_many):
         word = _srandom.choice(dictionary)
         words[word.lower()] = True
-        print(word, end='\n    ')
-    print("\n")
+        output_string += word + separator
 
-    if len(words) < howMany:
-        print("! Your random generator is weak")
-        print("! or you are being very lucky.")
+    print(output_string)
+
+    if len(words) < how_many:
+        sys.stderr.write("! You've drawn a word more than once, this means:\n"
+                         "! Your random generation is weak"
+                         " or you are being very lucky.\n")
         tainted = True
 
     if tainted:
-        print("!!! Don't use the resulting passphrase !!!")
+        sys.exit("!!! Don't use the resulting passphrase !!!")
 
 if __name__ == "__main__":
     main()
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)