nd_sys_prog/homework05/hulk.py

126 lines
3.4 KiB
Python
Raw Normal View History

2025-02-25 23:09:16 -05:00
#!/usr/bin/env python3
from typing import Iterable, Iterator
import concurrent.futures
import hashlib
import os
import string
import sys
# Constants
ALPHABET = string.ascii_lowercase + string.digits
# Functions
def usage(exit_code: int=0):
print('''Usage: hulk.py [-a ALPHABET -c CORES -l LENGTH -p PATH -s HASHES]
-a ALPHABET Alphabet to use in permutations
-c CORES CPU Cores to use
-l LENGTH Length of permutations
-p PREFIX Prefix for all permutations
-s HASHES Path of hashes file''', file=sys.stderr)
sys.exit(exit_code)
def sha1sum(s: str) -> str:
''' Compute SHA1 digest for given string.
>>> sha1sum('a')
'86f7e437faa5a7fce15d1ddcb9eaeaea377667b8'
'''
# TODO: Use the hashlib library to produce the SHA1 hex digest of the given
# string.
return ''
def permutations(length: int, alphabet: str=ALPHABET) -> Iterator[str]:
''' Recursively yield all permutations of alphabet up to given length.
>>> for p in permutations(2, 'ab'): print(p)
aa
ab
ba
bb
'''
# TODO: Use yield to create a generator function that recursively produces
# all the permutations of the given alphabet up to the provided length.
yield ''
def flatten(sequence: Iterable[Iterable[str]]) -> Iterator[str]:
''' Flatten sequence of iterables.
>>> for p in flatten([['a', 'b'], ['c', 'd']]): print(p)
a
b
c
d
'''
# TODO: Iterate through sequence and yield from each iterator in sequence.
yield ''
def crack(hashes: set[str], length: int, alphabet: str=ALPHABET, prefix: str='') -> list[str]:
''' Return all password permutations of specified length that are in hashes
by trying all possible permutations sequentially.
>>> for p in crack({sha1sum(l) for l in 'abc'}, 1, 'abcd'): print(p)
a
b
c
'''
# TODO: Return list comprehension that iterates over a sequence of
# candidate permutations and checks if the sha1sum of each candidate is in
# hashes.
return []
def whack(arguments: tuple[set[str], int, str, str]) -> list[str]:
''' Call the crack function with the specified list of arguments
>>> for p in whack([{sha1sum(l) for l in 'abc'}, 1, 'abcd', '']): print(p)
a
b
c
'''
return []
def smash(hashes: set[str], length: int, alphabet: str=ALPHABET, prefix: str='', cores: int=1) -> Iterator[str]:
''' Return all password permutations of specified length that are in hashes
by cracking subsets of all possible permutations concurrently.
>>> for p in smash({sha1sum(l) for l in 'abc'}, 1, 'abcd'): print(p)
a
b
c
'''
# TODO: Create generator expression with arguments to pass to whack and
# then use ProcessPoolExecutor to apply whack to all items in expression.
yield ''
# Main Execution
def main(arguments: list[str]=sys.argv[1:]) -> None:
''' Smashes given hashes to determine passwords with specified alphabet,
length, and prefix. Uses multiple cores (ie. processes) if specified.
>>> main('-a abcdefg -l 2'.split())
cg
fg
gg
'''
alphabet = ALPHABET
cores = 1
hashes_path = 'hulk.hashes'
length = 1
prefix = ''
# TODO: Parse command line arguments
# TODO: Load hashes set
# TODO: Execute smash function
# TODO: Print all found passwords
if __name__ == '__main__':
main()
# vim: set sts=4 sw=4 ts=8 expandtab ft=python: