Last active
July 8, 2017 23:04
-
-
Save kylethebaker/e0863efff88343748dd2bd85ad84661b to your computer and use it in GitHub Desktop.
This file contains 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 characters
def encode(key, pt): | |
"""Encodes the plaintext using key.""" | |
return "".join([encode_single(x, y) for x, y in get_pairs(key, pt)]) | |
def decode(key, ct): | |
"""Decodes the ciphertext using key.""" | |
return "".join([decode_single(x, y) for x, y in get_pairs(key, ct)]) | |
def encode_single(key, char): | |
"""Encodes a single character. | |
To encode, we start at the keys position in the alphabet and move 'char' | |
characters forwards. If the resulting character moves passed Z then we | |
cycle back to A. | |
""" | |
index = (index_from_alpha(char) + index_from_alpha(key)) % 26 | |
return alpha_from_index(index) | |
def decode_single(key, char): | |
"""Decodes a single character. | |
Decoding is similiar to encoding, except we start at the ciphertext char | |
and move 'key' characters backwards, looping back around if we go out | |
of bounds. | |
""" | |
index = (index_from_alpha(char) - index_from_alpha(key)) % 26 | |
return alpha_from_index(index) | |
def get_pairs(key, string): | |
"""Zips normalized string with normalized and padded key.""" | |
string = normalize(string) | |
key = pad_key(normalize(key), len(string)) | |
return zip(key, string) | |
def normalize(text): | |
"""Uppercases and removes all non-alpha characters.""" | |
return list(filter(str.isalpha, text.upper())) | |
def pad_key(key, length): | |
"""Pads (or truncates) the key by repeating itself.""" | |
for i in range(length - len(key)): | |
key += key[i % len(key)] | |
return key[:length] | |
def index_from_alpha(char): | |
"""Given a character, returns it's position in the alphabet. | |
Since we are dealing with normalized strings, all characters should be | |
in the ascii range between 65 (A) and 90 (Z), allowing us to substract | |
65 to get 0 for A and 25 for Z. | |
""" | |
return ord(char) - 65 | |
def alpha_from_index(index): | |
"""Given a position in the alphabet, returns the corresponding character. | |
Adding 65 will bring us back to the character decimal value in the | |
uppercase ascii range. | |
""" | |
return chr(index + 65) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment