diff --git a/vs/python/README.md b/vs/python/README.md new file mode 100644 index 0000000..7a7aa18 --- /dev/null +++ b/vs/python/README.md @@ -0,0 +1,48 @@ +## 3.9 +```bash +python3 --version +Python 3.9.6 + +for i in {1..5}; do python3 password_cracking_sequential.py; done + +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 57.982330167 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 58.270694084 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 58.165215833999994 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 58.549774666999994 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 57.801265541 +``` + +## 3.11.8 +```bash +python3.11 --version +Python 3.11.8 + +python3.11 password_cracking_sequential.py +➜ Chapter 2 git:(master) for i in {1..5}; do python3.11 password_cracking_sequential.py; done + +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 48.50309233300504 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 48.76890112500405 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 48.461341125002946 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 48.608549166005105 +Processing number combinations sequentially +PASSWORD CRACKED: 87654321 +PROCESS TIME: 48.863172917001066 +``` \ No newline at end of file diff --git a/vs/python/password_cracking_sequential.py b/vs/python/password_cracking_sequential.py new file mode 100644 index 0000000..8aa10e3 --- /dev/null +++ b/vs/python/password_cracking_sequential.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3.9 + +"""Program for cracking the password consisting with only numbers using brute +force approach sequentially""" + +import time +import math +import hashlib +import typing as T + + +def get_combinations(*, length: int, min_number: int = 0, + max_number: T.Optional[int] = None) -> T.List[str]: + """Generate all possible password combinations""" + combinations = [] + if not max_number: + # calculating maximum number based on the length + max_number = int(math.pow(10, length) - 1) + + # go through all possible combinations in a given range + for i in range(min_number, max_number + 1): + str_num = str(i) + # fill in the missing numbers with zeros + zeros = "0" * (length - len(str_num)) + combinations.append("".join((zeros, str_num))) + return combinations + + +def get_crypto_hash(password: str) -> str: + """"Calculating cryptographic hash of the password""" + return hashlib.sha256(password.encode()).hexdigest() + + +def check_password(expected_crypto_hash: str, + possible_password: str) -> bool: + actual_crypto_hash = get_crypto_hash(possible_password) + # compare the resulted cryptographic hash with the one stored in the system + return expected_crypto_hash == actual_crypto_hash + + +def crack_password(crypto_hash: str, length: int) -> None: + """Brute force the password combinations""" + print("Processing number combinations sequentially") + start_time = time.perf_counter() + combinations = get_combinations(length=length) + for combination in combinations: + if check_password(crypto_hash, combination): + print(f"PASSWORD CRACKED: {combination}") + break + + process_time = time.perf_counter() - start_time + print(f"PROCESS TIME: {process_time}") + + +if __name__ == "__main__": + crypto_hash = \ + "e24df920078c3dd4e7e8d2442f00e5c9ab2a231bb3918d65cc50906e49ecaef4" + length = 8 + crack_password(crypto_hash, length)