You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.8 KiB
Python

import argparse
import re
import vig
import os
def probe(key, substrings, words):
key_hits = {}
for x in range(ord('a'), ord('z')+1):
count = 0
for substr in substrings:
if re.search(vig.decrypt(key+chr(x), substr[0:len(key)+1]), words):
count += 1
key_hits[key+chr(x)] = count
best_val = [val for key, val in sorted(
key_hits.items(), key=lambda ele: ele[1])][-1]
return {key: val for key, val in key_hits.items() if val == best_val}
def remove_crap_from_list(tree, max_depth, thr):
best = [-x * thr for x in range(max_depth+2)]
for key, val in tree.items():
if val > best[len(key)]:
best[len(key)] = val
import copy
tmp = copy.copy(list(tree.items()))
for key, val in tmp:
for i in range(len(key), max_depth+1):
if val < (best[i] - thr + (i-len(key))*thr*1.5):
del tree[key]
break
def crack(substrings, words):
tree = {"": 0}
while tree:
curr = [key for key, val in sorted(
tree.items(), key=lambda ele: ele[1])][-1]
if len(curr) == len(substrings[0]):
return curr
del tree[curr]
tree.update(probe(curr, substrings, words))
remove_crap_from_list(tree, len(substrings[0]), 10)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('FILE')
parser.add_argument('--keylen', type=int, metavar="INT", required=True)
args = parser.parse_args()
t = ''.join([x for x in open(args.FILE, "r").read().lower() if x.isalpha()])
substrings = [(t[i:i+args.keylen]) for i in range(0, len(t), args.keylen)]
words = open(os.path.abspath(os.path.dirname(__file__))+"/words.txt", "r").read()
print(crack(substrings, words))