Created
October 11, 2018 13:53
-
-
Save notwa/47dcb49b0fbf3cc79acb76ad72a267cc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# dead simple dictionary attack for fixed-length passwords. | |
# this is far from optimal. | |
from collections import defaultdict | |
import argparse | |
import sys | |
import random | |
program = sys.argv[0] | |
args = sys.argv[1:] | |
parser = argparse.ArgumentParser( | |
description="attack: produce fixed-length strings from dictionaries") | |
parser.add_argument( | |
'length', type=int, | |
help="the length of the strings to output") | |
parser.add_argument( | |
'path', metavar='text-file', nargs='+', | |
help="a dictionary file containing one string per line") | |
parser.add_argument( | |
'-n', metavar='limit', type=float, default='inf', | |
help="output this many strings and exit") | |
parser.add_argument( | |
'-s', metavar='seed', type=int, default=None, | |
help="use as a seed for the random number generator") | |
a = parser.parse_args(args) | |
seed = a.s | |
limit = a.n | |
paths = a.path | |
fixed_length = a.length | |
del a | |
lines = [] | |
for path in paths: | |
with open(path, "r") as f: | |
for line in f: | |
lines.append(line.strip('\r\n')) | |
nlines = defaultdict(lambda: []) | |
ncount = defaultdict(lambda: 0) | |
for line in lines: | |
length = len(line) | |
if length == 0 or length > fixed_length: | |
continue | |
nlines[length].append(line) | |
ncount[length] += 1 | |
del lines | |
if seed is not None: | |
random.seed(seed) | |
lengths = list(ncount.keys()) | |
length_weights = list(ncount.values()) | |
i = 0 | |
while i < limit: | |
s = '' | |
new_weights = length_weights.copy() | |
while len(s) < fixed_length: | |
if len(s) > 0: | |
for j, length in enumerate(lengths): | |
if len(s) + length > fixed_length: | |
new_weights[j] = 0 | |
if sum(new_weights) == 0: | |
s = '' | |
new_weights = length_weights.copy() | |
continue | |
chosen_length = random.choices(lengths, new_weights)[0] | |
s += random.choice(nlines[chosen_length]) | |
try: | |
print(s) | |
except OSError: | |
# pipe closed. | |
break | |
i += 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment