-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbrute_force.py
51 lines (41 loc) · 1.93 KB
/
brute_force.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
from enigma.machine import EnigmaMachine
import argparse
from tqdm import tqdm
CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def brute_force(code: str, dictionary: list):
reflectors = ['B', 'C']
rotors = ['I', 'II', 'III', 'IV', 'V']
rotor_combinations = [f'{a} {b} {c}' for a in rotors for b in rotors for c in rotors]
ring_settings = [f'{a} {b} {c}' for a in CHARSET for b in CHARSET for c in CHARSET]
res = {}
for reflector in tqdm(reflectors, desc='Reflectors', position=0, leave=None):
for rotor_combination in tqdm(rotor_combinations, desc='Rotors', position=1, leave=None):
for ring_setting in tqdm(ring_settings, desc='Rings', position=2, leave=None):
e = EnigmaMachine.from_key_sheet(rotor_combination, ring_setting, reflector, plugboard_settings='HI')
dec = e.process_text(code)
score = 0
for word in dictionary:
if word in dec:
score += 1
if not score:
continue
rotor_settings = [f'{r}:{s}' for r, s in zip(rotor_combination.split(' '), ring_setting.split(' '))]
res[f'{dec} | [{" ".join(rotor_settings)}] + {reflector}'] = score
res = dict(sorted(res.items(), key=lambda x: x[1], reverse=True))
with open('results.txt', 'w') as f:
for k, v in res.items():
f.write(f'{v} | {k}\n')
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--code", '-c', help="Code to crack")
parser.add_argument("--dictionary", '-d', help="Dictionary file")
args = parser.parse_args()
with open(args.dictionary, 'r') as f:
dictionary = f.read().splitlines()
dictionary = [word.upper() for word in dictionary if len(word) >= 3]
code = args.code.upper()
while ' ' in code:
code = code.replace(' ', '')
brute_force(code, dictionary)
if __name__ == '__main__':
main()