Created
June 26, 2018 03:35
-
-
Save srli/fd1c67cba10cd95091d992152fc80d04 to your computer and use it in GitHub Desktop.
Revisions
-
srli created this gist
Jun 26, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ import string import random from collections import Counter """ An easy implementation of the Caesar cipher Written by Sophie Li, 2018 http://blog.justsophie.com/caesar-cipher-generator/ """ def encode_string(input_string): # Generate seed for shift seed = random.randint(0, len(string.ascii_lowercase)) # Create cipher dictionary by shifting alphabet over by "seed" places alphabet = list(string.ascii_lowercase) alphabet_shifted = alphabet[seed:] + alphabet[:seed] cipher_dict = dict(zip(alphabet, alphabet_shifted)) # Remove punctuation, spacing, and capitalization of input string clean_text = input_string.translate(None, string.punctuation).replace(" ", "").lower() # Encode string, adding a space every 4 letters for readability cipher_text = "" for ind, letter in enumerate(clean_text): cipher_text += cipher_dict[letter] if (ind+1)%4 == 0: cipher_text += " " return cipher_text """ There are a few ways to decode strings, but for this quick example, a frequency analysis can be a good starting point-- especially if your message is long. If the message is too short, there won't be enough data to do a good analysis. """ def cipher_freq_analysis(cipher_string): # Calculate histogram of cipher text cipher_hist = Counter(cipher_string.replace(" ", "")) # Find alphabet positions of 4 most common letters e_position = string.ascii_lowercase.index('e') a_position = string.ascii_lowercase.index('a') o_position = string.ascii_lowercase.index('o') i_position = string.ascii_lowercase.index('i') possible_seeds = [] for ind in range(1, 3): common_letter = cipher_hist.most_common(ind)[0][0] # Check distance between the cipher histogram and common letters e_distance = string.ascii_lowercase.index(common_letter) - e_position a_distance = string.ascii_lowercase.index(common_letter) - a_position o_distance = string.ascii_lowercase.index(common_letter) - o_position i_distance = string.ascii_lowercase.index(common_letter) - i_position # Add these distances as possible seeds possible_seeds += [e_distance, a_distance, o_distance, i_distance] return possible_seeds def decode_string_by_seed(cipher_string, seed): # Create cipher dictionary by shifting alphabet over by "seed" places alphabet = list(string.ascii_lowercase) alphabet_shifted = alphabet[seed:] + alphabet[:seed] decode_dict = dict(zip(alphabet_shifted, alphabet)) decode_dict[" "] = " " # Encode string, adding a space every 4 letters for readability decoded_text = "" for ind, letter in enumerate(cipher_string): decoded_text += decode_dict[letter] print decoded_text def decode_string(cipher_string): possible_seeds = cipher_freq_analysis(cipher_string) print "------" print "Decoding string by possible seeds. CTRL+C to exit at any time" for seed in possible_seeds: print "------\n " decode_string_by_seed(cipher_string, seed) raw_input("") if __name__ == '__main__': raw_string = "Hi there, this is a sample string to be encoded. It's pretty normal looking." cipher_string = encode_string(raw_string) print "Ecoded string: ", cipher_string decode_string(cipher_string)