"""Password Cracker, by Al Sweigart. Displays changing random characters while gradually revealing a hidden phrase. After holding the completed phrase for five seconds, a new phrase begins. """ import os import random import time # Phrases that may be selected at the start of each cracking cycle. MESSAGES = ( "It was the best of times, it was the worst of times...", "It was a bright cold day in April, and the clocks were striking thirteen.", "Too many secrets.", "S W O R D F I S H", "Common sense is very rare.", "I refuse to join any club that would have me as a member.", "Speak when you are angry and you will make the best speech you will ever regret.", "Experience is simply the name we give our mistakes.", "Judge a man by his questions rather than by his answers.", "There is no cure for curiosity.", "Three may keep a secret, if two of them are dead.", "A book must be the axe for the frozen sea within us.”", "Freedom is what you do with what’s been done to you.", "In a hole in the ground there lived a hobbit.", "I am an invisible man.", "The sky above the port was the color of television, tuned to a dead channel.", ) # Pause after each changing row in seconds. DELAY = 0.01 # Characters randomly displayed in columns that are not locked. CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" # Chance from 0 to 1 of locking one more column on each row. UNLOCK_CHAR_PROBABILITY = 0.04 # Text inserted between the displayed columns. The default keeps characters # adjacent; phrases such as "S W O R D F I S H" contain their own spaces. SPACER = "" # Seconds to hold the completed phrase before beginning again. FINISHED_PAUSE = 5 def crack_message(message): """Animate one phrase until every column has been revealed.""" locked_columns = [False] * len(message) number_locked = 0 while number_locked < len(message): columns = [random.choice(CHARS) for _ in message] if random.random() < UNLOCK_CHAR_PROBABILITY: unlocked_columns = [ index for index, is_locked in enumerate(locked_columns) if not is_locked ] column_to_lock = random.choice(unlocked_columns) locked_columns[column_to_lock] = True number_locked += 1 for index, is_locked in enumerate(locked_columns): if is_locked: columns[index] = message[index] print(SPACER.join(columns)) time.sleep(DELAY) # Print the completed phrase a few more times before holding it on screen. for _ in range(9): print(SPACER.join(message)) time.sleep(DELAY) def main(): os.system("cls" if os.name == "nt" else "clear") while True: crack_message(random.choice(MESSAGES)) time.sleep(FINISHED_PAUSE) if __name__ == "__main__": try: main() except KeyboardInterrupt: pass