Skip to content

Instantly share code, notes, and snippets.

@kylethebaker
Last active July 8, 2017 23:04
Show Gist options
  • Save kylethebaker/e0863efff88343748dd2bd85ad84661b to your computer and use it in GitHub Desktop.
Save kylethebaker/e0863efff88343748dd2bd85ad84661b to your computer and use it in GitHub Desktop.
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