* Switched order of leading/trailing char/digits

* added separator between leading/trailing chars/digits
* added experimental unmunching of hunspell dictionary... probably useless
This commit is contained in:
Fredrik Eriksson 2017-05-04 18:47:23 +02:00
parent f2ae6cecbe
commit ec3a51c23e

View File

@ -3,8 +3,7 @@
import math import math
import os import os
import sys import sys
#import secrets as random import subprocess
import random
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
import ConfigParser as configparser import ConfigParser as configparser
@ -18,6 +17,9 @@ else:
do_seed = True do_seed = True
import random import random
class DictReadError(Exception):
pass
class PasswordLengthError(Exception): class PasswordLengthError(Exception):
pass pass
@ -82,10 +84,43 @@ def get_config(f_name):
conf.read(f_name) conf.read(f_name)
return conf return conf
def _read_dictionary(f_name, word_min_chars, word_max_chars): def _read_dictionary(conf):
lang = conf.get('dictionary', 'lang')
word_min_chars = conf.getint('dictionary', 'word_min_char')
word_max_chars = conf.getint('dictionary', 'word_max_char')
dict_file = os.path.join(conf.get('dictionary', 'myspell_dir'), '{}.dic'.format(conf.get('dictionary', 'lang')))
aff_file = os.path.join(conf.get('dictionary', 'myspell_dir'), '{}.aff'.format(conf.get('dictionary', 'lang')))
unmunch_bin = conf.get('dictionary', 'unmunch_bin')
words = set() words = set()
chars = 0 chars = 0
with open(f_name, 'r') as f: if os.path.exists(aff_file) and unmunch_bin:
with open(os.devnull, 'w') as null:
proc = subprocess.Popen(
[ unmunch_bin, dict_file, aff_file ],
stdout=subprocess.PIPE,
stderr=null
)
out, err = proc.communicate()
if proc.returncode != 0:
raise DictReadError('Unmunching dictionaries failed')
for word in out.splitlines():
save = word.strip().decode('utf-8')
if not save:
continue
first_char = save[:1]
last_char = save[-1]
if first_char in '1234567890,.-:':
continue
if last_char in '-':
continue
if word_min_chars and len(save) < word_min_chars:
continue
if word_max_chars and len(save) > word_max_chars:
continue
words.add(save)
chars += len(save)
else:
with open(dict_file, 'r') as f:
for line in f: for line in f:
if not line: if not line:
continue continue
@ -121,10 +156,7 @@ def generate_passwords(conf):
if do_seed: if do_seed:
random.seed() random.seed()
res = {} res = {}
dict_data = _read_dictionary( dict_data = _read_dictionary(conf)
os.path.join(conf.get('dictionary', 'myspell_dir'), '{}.dic'.format(conf.get('dictionary', 'lang'))),
conf.getint('dictionary', 'word_min_char'),
conf.getint('dictionary', 'word_max_char'))
words = dict_data['words'] words = dict_data['words']
word_length = dict_data['wordlength'] word_length = dict_data['wordlength']
@ -175,7 +207,11 @@ def generate_passwords(conf):
trailing_digits = ''.join(random.choice('1234567890') for i in range(nr_of_td)) trailing_digits = ''.join(random.choice('1234567890') for i in range(nr_of_td))
leading_chars = ''.join(random.choice(special_chars) for i in range(nr_of_lc)) leading_chars = ''.join(random.choice(special_chars) for i in range(nr_of_lc))
trailing_chars = ''.join(random.choice(special_chars) for i in range(nr_of_tc)) trailing_chars = ''.join(random.choice(special_chars) for i in range(nr_of_tc))
pwd = '{ld}{lc}{base}{tc}{td}'.format( if leading_digits or leading_chars:
base_pwd = "{}{}".format(separator, base_pwd)
if trailing_digits or trailing_chars:
base_pwd = "{}{}".format(base_pwd, separator)
pwd = '{lc}{ld}{base}{td}{tc}'.format(
lc=leading_chars, lc=leading_chars,
ld=leading_digits, ld=leading_digits,
base=base_pwd, base=base_pwd,