"""Caesar cipher solver.""" # variables go here # the "alphabet" string is used for moving letters up and down the alphabet alphabet = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" # the "letter_list" list is used for collecting the finished letters, # and then later turning them into a string and printing it letter_list = [] # the "user_input" string is used for collecting the user's string user_input = "" # functions here def show_instructions(): """Print instructions.""" print("") print("The Caesar Cipher is a method of encrypting text.") print("It works by simply shifting letters along the alphabet by a set amount of characters.") print("For example, the letter A will become B if encrypted with a key of 1.") print("Decrypting will do the opposite.") print("For example, the letter B will become A if decrypted with a key of 1.") print("") print("To use this program, input your desired text, then select an option and enter a key.") print("The key is the amount of spaces you want each letter to be moved by.") print("") print("The encode function moves letters to the right of the alphabet.") print("This should be used on a string that hasn't yet been encrypted.") print("") print("The decode function moves letters to the left of the alphabet instead.") print("This should be used on a previously encrypted string.") print("") print("The crack function will automatically print every possible outcome that could be made using Caesar Cipher.") print("This could be used when you know a string is encrypted but you do not know the key.") print("After using this, look through all of the outputs and see if one of them makes sense.") print("") print("Please note that Caesar Cipher is a very bad method of encryption and provides no security.") print("Do not use this program to encrypt any important messages. This is just for fun.") print("") # the "increment_repeat" integer is used for keeping track of the current letter def encode(increment_repeat=0): """Encode strings.""" # repeats until the entire string has been encoded for x in range(0, letter_amount): # if the selected letter is a space, add a space to the list, continue if not a space if (input_string[0 + increment_repeat]) == " ": increment_repeat += 1 letter_list.append(" ") # if the selected letter is an uppercase letter, get unicode code point then # match it with the alphabet string and move it up a certain amount of spaces based on key # with a certain offset to make it work correctly with uppercase letters # then add to list as uppercase letter elif (input_string[0 + increment_repeat]).isupper(): letter = ord(input_string[0 + increment_repeat]) increment_repeat += 1 letter_list.append(alphabet.upper()[(letter - 97) + key + 6]) # if the selected letter is a lowercase letter, get unicode point then # match it with the alphabet string and move it up a certain amount of spaces based on key # then add to list as lowercase letter elif (input_string[0 + increment_repeat]).isalpha(): letter = ord(input_string[0 + increment_repeat]) increment_repeat += 1 letter_list.append(alphabet[(letter - 97) + key]) # if none of the earlier requirements are met, do not add to the list and skip to the next letter else: increment_repeat += 1 letter_list.append(input_string[-1 + increment_repeat]) # the "increment_repeat" integer is used for keeping track of the current letter def decode(increment_repeat=0): """Decode strings.""" # repeats until the entire string has been decoded for x in range(0, letter_amount): # if the selected letter is a space, add a space to the list if (input_string[0 + increment_repeat]) == " ": increment_repeat += 1 letter_list.append(" ") # if the selected letter is an uppercase letter, get unicode code point then # match it with the alphabet string and move it down a certain amount of spaces based on key # with a certain offset to make it work correctly with uppercase letters # then add to list as uppercase letter elif (input_string[0 + increment_repeat]).isupper(): letter = ord(input_string[0 + increment_repeat]) increment_repeat += 1 letter_list.append(alphabet.upper()[(letter - 97) - key + 6]) # if the selected letter is a lowercase letter, get unicode point then # match it with the alphabet string and move it down a certain amount of spaces based on key # then add to list as lowercase letter elif (input_string[0 + increment_repeat]).isalpha(): letter = ord(input_string[0 + increment_repeat]) increment_repeat += 1 letter_list.append(alphabet[(letter - 97) - key]) # if none of the earlier requirements are met, add the character to the list as is, and continue else: increment_repeat += 1 letter_list.append(input_string[-1 + increment_repeat]) # the "increment_repeat" integer is used for keeping track of the current letter def crack(increment_repeat=0, crack_list=None): """Automatically prints every possible string.""" if crack_list is None: crack_list = [] # repeats for every possible key # the "crack_phase" integer is essentially the key, # but it is automatically ticked up with every repeat and is used for automatic purposes for crack_phase in range(0, 26): # repeats until the entire string has been decoded for x in range(0, letter_amount): # if the selected letter is a space, add a space to the list, continue if not a space if (input_string[0 + increment_repeat]) == " ": increment_repeat += 1 crack_list.append(" ") # if the selected letter is an uppercase letter, get unicode code point then # match it with the alphabet string and move it down a certain amount of spaces based on key # with a certain offset to make it work correctly with uppercase letters # then add to list as uppercase letter elif (input_string[0 + increment_repeat]).isupper(): letter = ord(input_string[0 + increment_repeat]) increment_repeat += 1 crack_list.append(alphabet.upper()[(letter - 97) + crack_phase + 6]) # if the selected letter is a lowercase letter, get unicode point then # match it with the alphabet string and move it down a certain amount of spaces based on key # then add to list as lowercase letter elif (input_string[0 + increment_repeat]).isalpha(): letter = ord(input_string[0 + increment_repeat]) increment_repeat += 1 crack_list.append(alphabet[(letter - 97) + crack_phase]) # if none of the earlier requirements are met, add the character to the list as is, and continue else: increment_repeat += 1 crack_list.append(input_string[-1 + increment_repeat]) # converts the list into a string, then prints it crack_string = ''.join(crack_list) print(crack_string) # ticks up the key crack_phase += 1 # selects the first letter again increment_repeat = 0 # resets the list crack_list = [] # after this, the loop starts again until every possible string has been printed print() print("Every possible string has been printed.") print("Check all of the strings and see if any of them reveal a message.") print("If not, then the original string was probably" " not encrypted using Caesar Cipher.") while True: instructions_input = input("read instructions? (yes/no) ") if instructions_input == "y" or instructions_input == "yes": show_instructions() break if instructions_input == "n" or instructions_input == "no": break else: print("Please choose an option") input_string = input("string? ") letter_amount = len(input_string) while True: user_input = input("decode, encode or crack? ") if user_input == "decode" or user_input == "encode" \ or user_input == "crack": break else: print("Please choose an option") if user_input == "encode" or user_input == "decode": while True: key = int(input("key? ")) if 27 > key > -27: break else: print("key must be below 27 and above -27") while True: if user_input == "decode": decode() break elif user_input == "encode": encode() break elif user_input == "crack": crack() break # converts the previously made list into a string printable_string = ''.join(letter_list) # prints the final decoded/encoded string print(printable_string)