From 4632880435a388da98142262bb166008d171bebf Mon Sep 17 00:00:00 2001
From: ulif <uli@gnufix.de>
Date: Wed, 28 Jan 2015 09:01:56 +0100
Subject: [PATCH] First sketch of main password generator.

---
 diceware/diceware.py   | 20 ++++++++++++++++++++
 tests/test_diceware.py | 10 +++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/diceware/diceware.py b/diceware/diceware.py
index 63d7029..482950c 100644
--- a/diceware/diceware.py
+++ b/diceware/diceware.py
@@ -1,5 +1,7 @@
 import os
 import re
+from random import SystemRandom
+
 
 #: The directory in which wordlists are stored
 SRC_DIR = os.path.dirname(__file__)
@@ -7,6 +9,8 @@ SRC_DIR = os.path.dirname(__file__)
 #: A regular expression matching ASCII chars
 RE_ASCII_CHARS = re.compile('^[a-zA-Z]{2}$')
 
+#: Special chars inserted on demand
+SPECIAL_CHARS = "~!#$%^&*()-=+[]\{}:;\"'<>?/0123456789"
 
 def get_wordlist(path):
     """Parse file at `path` and build a word list of it.
@@ -43,5 +47,21 @@ def get_wordlist_path(lang):
     return os.path.abspath(os.path.join(SRC_DIR, basename.lower()))
 
 
+def get_passphrase(wordnum=6, specials=True, separator='', lang='en',
+                   capitalized=True):
+    """Get a diceware passphrase.
+    """
+    word_list = get_wordlist(get_wordlist_path(lang))
+    rnd = SystemRandom()
+    words = [rnd.choice(word_list) for x in range(wordnum)]
+    if capitalized:
+        words = [x.capitalize() for x in words]
+    result = separator.join(words)
+    result = list(result)
+    result[rnd.choice(range(len(result)))] = rnd.choice(SPECIAL_CHARS)
+    result = ''.join(result)
+    return result
+
+
 def main():
     pass
diff --git a/tests/test_diceware.py b/tests/test_diceware.py
index 5ed8c7b..273169d 100644
--- a/tests/test_diceware.py
+++ b/tests/test_diceware.py
@@ -1,6 +1,8 @@
 import os
 import pytest
-from diceware.diceware import SRC_DIR, get_wordlist, get_wordlist_path
+from diceware.diceware import (
+    SRC_DIR, get_wordlist, get_wordlist_path, get_passphrase,
+    )
 
 
 class Test_GetWordList(object):
@@ -57,3 +59,9 @@ class TestDicewareModule(object):
         assert os.path.basename(get_wordlist_path('de')) == 'wordlist_de.asc'
         assert os.path.basename(get_wordlist_path('De')) == 'wordlist_de.asc'
         assert os.path.basename(get_wordlist_path('DE')) == 'wordlist_de.asc'
+
+    def test_get_passphrase(self):
+        # we can get passphrases
+        r1 = get_passphrase()
+        r2 = get_passphrase()
+        assert r1 != r2
-- 
GitLab