def find_password_iter(brute_force_limit: int = 3) -> Iterator[str]: length = find_length() q: PriorityQueue[Tuple[float, str]] = PriorityQueue() q.put((0.0, "")) while not q.empty(): t, p = q.get() yield p if len(p) == length - brute_force_limit: # Brute force if there are not that many characters left i = 0 for chars in product(characters, repeat=length - len(p)): np = p + "".join(chars) if i == 0: yield np i = (i + 1) % 50 if check_password_vulnerable(np): yield np return else: # Search using a depth first search for c in characters: np = p + c if check_password_vulnerable(np): yield np return q.put((-time_password(pad(np, length)), np)) return
def find_length() -> int: NUMBER = 20000 times = [ timeit(lambda: check_password_vulnerable(" " * length), number=NUMBER) for length in range(21) ] return times.index(max(times))
def brute_force(password: str, length: int) -> Optional[str]: for chars in product(characters, repeat=length - len(password)): new_password = password + "".join(chars) if check_password_vulnerable(new_password): return new_password return None
def time_password(password: str, number: int = 40000) -> float: return timeit(lambda: check_password_vulnerable(password), number=number)
return q.put((-time_password(pad(np, length)), np)) return def find_password() -> str: for password in find_password_iter(): pass return password if __name__ == "__main__": from rich.console import Console import sys console = Console() console.show_cursor(False) for p in find_password_iter(): console.control("\r\033[K") console.print(f"[red]{p}[/]", end="") console.control("\r\033[K") if check_password_vulnerable(p): console.print(f"[green]{p}[/]") else: console.print(f"[red]Not found[/]") console.show_cursor(True)