Skip to content

Instantly share code, notes, and snippets.

@barisere
Created January 21, 2020 10:23
Show Gist options
  • Save barisere/cf57c33eb826156f6b2e6b78f6b087c6 to your computer and use it in GitHub Desktop.
Save barisere/cf57c33eb826156f6b2e6b78f6b087c6 to your computer and use it in GitHub Desktop.
A boring command line program that encrypts or decrypts text using Caesar cipher.
import sys
def normalize(c: str):
"""
Given c, a string of only one character, normalize returns the
character position of c in the English alphabet, with 'a' | 'A' = 0
and 'z' | 'Z' = 25, and an indication of whether c was uppercase.
Only alphabetic ASCII characters are transformed.
"""
if not (c.isascii() and c.isalpha()):
return None
return {
'isupper': c.isupper(),
'ord': ord(c) - ord('A') if c.isupper() else ord(c) - ord('a')
}
def restore(o):
return o['ord'] + ord('A') if o['isupper'] else o['ord'] + ord('a')
def caesar_formula(text: str, shift_key: str, char_transform):
"""
caesar_formula is the common procedure for either encrypting
or decrypting text using the Caesar shift substitution cipher.
The only part that varies is the shift operation which either
adds or subtracts the shift_key from the character code. That
part is parameterised as char_transform.
"""
return_value = ""
for c in text:
normalized_char = normalize(c)
if not normalized_char:
continue
shift = char_transform(normalized_char['ord'], shift_key) % 26
shift = restore({ 'isupper': normalized_char['isupper'], 'ord': shift })
return_value = return_value + chr(shift)
return return_value
def caesar_decrypt(cipher_text: str, shift_key: int):
"""
Decrypts cipher_text using shift_key. cipher_text must have been encrypted
using shift_key, else the result may be incorrect.
"""
return caesar_formula(cipher_text, shift_key, lambda n1, n2: n1 - n2)
def caesar_encrypt(plain_text: str, shift_key: int):
"""
Encrypts plain_text using shift_key.
"""
return caesar_formula(plain_text, shift_key, lambda n1, n2: n1 + n2)
if __name__ == "__main__":
usage = """
{} <command> <text> <key>
Args:
text string - the text to encrypt or decrypt
key number - the shift key
Commands:
encrypt - encrypts <text> using <key>
decrypt - decrypts <text> using <key>
""".format(sys.argv[0])
handlers = {
"decrypt": caesar_decrypt,
"encrypt": caesar_encrypt,
}
def default_handler():
print(usage)
exit(1)
try:
command, text, key = sys.argv[1], sys.argv[2], int(sys.argv[3])
handler = handlers.get(command, default_handler)
result = handler(text, key)
print(result)
exit(0)
except IndexError:
print(usage)
exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment