-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPassGrid.py
151 lines (119 loc) · 4.3 KB
/
PassGrid.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import itertools, random, json, os
from lib import PassGrid_Config
class PassGrid:
def __init__(self, config):
self.config = config.config
self.IMPORTED_WORDLIST = {}
self.working_wordlist = {}
self.generated_columns = {}
self.working_passgrid = {}
# Set random seed by using the value found in settings
random.seed(self.config['SETTINGS']['gridseed'])
# Main generator of object
def create_passgrid(self):
complete = False
# First, open the wordlist specified in config
file_opened = self.open_wordlist_file()
if file_opened is True:
# Randomize this list based on gridseed
list_ready = self.prepare_wordlist()
if list_ready is True:
# Make columns
columns_ready = self.prepare_columns()
if columns_ready is True:
# Create actual Grid
complete = self.generate_passgrid()
if complete is True:
msg = "Grid generated successfully!"
else:
msg = "Grid generation failed!"
return msg
# Open wordlist dictated in settings
def open_wordlist_file(self):
with open(self.config['SETTINGS']['listsdir'] + self.config['SETTINGS']['wordfile'], 'r') as f:
# Add to object
self.IMPORTED_WORDLIST = json.load(f)
return True
# Using a gridseed means that randomization is deterministic (i.e. can be replicated)
def prepare_wordlist(self):
# Get the loaded list
wordlist = self.IMPORTED_WORDLIST
TOTAL_CELLS = int(self.config['SETTINGS']['gridcols']) * int(self.config['SETTINGS']['gridrows'])
# When the imported wordlist cannot fill all cells, pull duplicates to populate
if (len(wordlist) < TOTAL_CELLS):
# How many additional words we need
words_to_add = TOTAL_CELLS - len(wordlist)
# Get those words
add_to_wordlist = random.choices(wordlist, k=words_to_add)
# Add to existing list
wordlist.extend(add_to_wordlist)
# Shuffle based on the seed
random.shuffle(wordlist)
# Populate object with new values matching total number of values needed
self.working_wordlist = wordlist[0:TOTAL_CELLS]
return True
# Make Excel-like columns
def prepare_columns(self):
NUMBER_OF_COLUMNS = int(self.config['SETTINGS']['gridcols'])
COLUMN_NAMES = self.config['SETTINGS']['colnames']
# When you have less columns than values to iterate against, use single char
if (NUMBER_OF_COLUMNS <= len(COLUMN_NAMES)):
prod = itertools.product(COLUMN_NAMES)
# Otherwise, always start with at least 2 values
else:
repeatcols = (NUMBER_OF_COLUMNS // len(COLUMN_NAMES)) + 1
prod = itertools.product(COLUMN_NAMES, repeat=repeatcols)
result = []
for values in prod:
result.append(''.join(values))
# Populate object with only values needed
self.generated_columns = result[0:NUMBER_OF_COLUMNS]
return True
# Apply the order of the wordlist to the columns we created
# Order is left to right, top to bottom (e.g. A1, B1, C1, A2, B2, C2, etc.)
def generate_passgrid(self):
WORDLIST = self.working_wordlist
COLUMNS = self.generated_columns
this_column = 0
this_row = 1
result = {}
i = 0
# Iterate over wordlist
for this_word in WORDLIST:
this_cell = COLUMNS[this_column] + str(this_row).zfill(2)
result[this_cell] = this_word
# Compare current column with total columns minus 1 since lists start at 0
if this_column // (len(COLUMNS)-1) == 0:
# Increment column
this_column += 1
else:
# Reset column
this_column = 0
# Increment row
this_row += 1
i += 1
self.working_passgrid = result
return True
def save_passgrid(self):
# Check if savesdir path exists, otherwise create it
if not os.path.exists(self.config['SETTINGS']['savesdir']):
os.makedirs(self.config['SETTINGS']['savesdir'])
# Save to file
with open(self.config['SETTINGS']['savesdir'] + self.config['SETTINGS']['gridjson'], 'w') as f:
json.dump(self.working_passgrid, f)
return True
def main():
# Generate config values
config = PassGrid_Config.PassGrid_Config()
config.init_config()
# PassGrid
passgrid = PassGrid(config)
passgrid.create_passgrid()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
try:
exit()
except SystemExit:
exit()