-
Notifications
You must be signed in to change notification settings - Fork 1
/
generator.py
executable file
·112 lines (94 loc) · 3.29 KB
/
generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python3
""" passworts cli for generating passwords"""
# import time
import pickle
import random
import bisect
from argparse import ArgumentParser
from collections import defaultdict
from pathlib import Path
from calc import preprocess, LOOKUP_RANGE
from preprocess_type import integer_dict
def makeup(counts, lookup_lenght):
"""make up a word using the markov model of the original text"""
previous_chars = 0, "^" * lookup_lenght
text = []
while previous_chars[1] != "$" * lookup_lenght:
possible_chars = counts[previous_chars]
random_char_propability = random.random()
# find key of dict with first value larger then propability
index = bisect.bisect(list(possible_chars.values()), random_char_propability)
next_char = list(possible_chars.keys())[index]
text.append(next_char)
previous_chars = previous_chars[0] + 1, previous_chars[1][1:] + next_char
return "".join(text)[:-lookup_lenght]
def text_import(text_path):
"""reads a file to analyse"""
try:
with open(text_path, "rb") as handle:
counts = pickle.load(handle)
except OSError as error:
raise SystemExit("Could not open text file: " + str(error)) from error
return counts
def words_import(words_path):
"""read words to prevent existing words"""
try:
with open(words_path, "r", encoding="utf-8") as word_file:
words = word_file.read()
except OSError as error:
raise SystemExit("Could not open words file: " + str(error)) from error
return words
def generate(
pw_lenght,
random_lenght,
source=Path(__file__).absolute().parent / "dict" / "text.txt",
):
"""generate word with limitations"""
# print ("reading...")
dict_path = Path(source)
words = words_import(Path(__file__).absolute().parent / "dict" / "words.txt")
if dict_path.with_suffix(".pkl").exists():
counts = text_import(dict_path.with_suffix(".pkl"))
else:
preprocess(dict_path)
counts = defaultdict(integer_dict)
counts = text_import(dict_path.with_suffix(".pkl"))
# print ("generating...")
for _ in range(50000):
madeup_word = makeup(counts, LOOKUP_RANGE).lower()
# break
if madeup_word not in words.lower() and madeup_word.isalpha():
if bool(random_lenght):
return madeup_word
if not bool(random_lenght) and len(madeup_word) == pw_lenght:
return madeup_word
# print(" " + str(i + 1) + "-crap: " + madeup_word)
print("Sorry this one took to long")
return "Sorry this one took to long"
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument(
"-f",
"--file",
type=Path,
dest="filename",
help="path of the input file",
default=Path(__file__).absolute().parent / "dict" / "text.txt",
)
parser.add_argument(
"-l",
"--lenght",
type=int,
help="lenght of the password",
default=8,
)
parser.add_argument(
"-a",
"--amount",
type=int,
help="amount of the passwords",
default=1,
)
args = parser.parse_args()
for i in range(args.amount):
print(generate(args.lenght, False, str(args.filename)))