I'm writing a simple brute force function with a ProcessPoolExecutor. The task is to find matching hashes of 8-digit passwords.
And I noticed a problem that if all given passwords are found, the function will be still looping.
I tried to implement a global counter variable, but as I soon realized, it is not shared between futures. Is there any way to create a counter or maybe something else that all processes will be aware of to cut the execution time?
Here is my executor manager:
def brute_force_password() -> None:
futures = []
with ProcessPoolExecutor(multiprocessing.cpu_count()) as executor:
for interval in range(len(PASSWORDS_TO_BRUTE_FORCE)):
futures.append(
executor.submit(
check_password_in_interval,
interval * 1_000_0000,
(interval + 1) * 1_000_0000
)
)
wait(futures)
And loop-checking function:
def check_password_in_interval(start: int, end: int) -> None:
for guess in range(start, end):
guess = f"{guess:08d}"
hashed_guess = sha256_hash_str(guess)
if hashed_guess in PASSWORDS_TO_BRUTE_FORCE:
index = PASSWORDS_TO_BRUTE_FORCE.index(hashed_guess)
HACKED_PASSWORDS[index] = guess
print(f"{hashed_guess} is {guess}.")
I'll appreciate your time and help!
What I tried: global and environment variables
you can try and use multiprocessing which allows you to share values across processes:
import multiprocessing
from concurrent.futures import ProcessPoolExecutor, wait
from ctypes import c_int
def brute_force_password(passwords_found: multiprocessing.Value) -> None:
futures = []
with ProcessPoolExecutor(multiprocessing.cpu_count()) as executor:
for interval in range(len(PASSWORDS_TO_BRUTE_FORCE)):
futures.append(
executor.submit(
check_password_in_interval,
interval * 1_000_0000,
(interval + 1) * 1_000_0000,
passwords_found
)
)
wait(futures)
def check_password_in_interval(start: int, end: int, passwords_found: multiprocessing.Value) -> None:
for guess in range(start, end):
guess = f"{guess:08d}"
hashed_guess = sha256_hash_str(guess)
if hashed_guess in PASSWORDS_TO_BRUTE_FORCE:
with passwords_found.get_lock():
index = PASSWORDS_TO_BRUTE_FORCE.index(hashed_guess)
HACKED_PASSWORDS[index] = guess
passwords_found.value += 1
print(f"{hashed_guess} is {guess}.")
if passwords_found.value == len(PASSWORDS_TO_BRUTE_FORCE):
return
if __name__ == '__main__':
passwords_found = multiprocessing.Value(c_int, 0)
brute_force_password(passwords_found)