Skip to content

Instantly share code, notes, and snippets.

@j3speaks
Created May 17, 2019 20:24
Show Gist options
  • Save j3speaks/b1885ffa42c1d46679e95471d2ba6f16 to your computer and use it in GitHub Desktop.
Save j3speaks/b1885ffa42c1d46679e95471d2ba6f16 to your computer and use it in GitHub Desktop.
Caesar Cipher written in Python
# Constant Values
DEFAULT_SHIFT = 1
MAX_ALPHABET_COUNT = 26
UPPERCASE_A_ASCII_CODE = 65
LOWERCASE_A_ASCII_CODE = 97
def encode(plaintext, shift=DEFAULT_SHIFT):
if not plaintext.isalpha():
raise ValueError("Invalid 'plaintext' argument value %s; it is not all alpha." % plaintext)
ciphertext = ""
for letter in plaintext:
if letter.isupper():
ciphertext += chr((ord(letter) + shift-UPPERCASE_A_ASCII_CODE) % MAX_ALPHABET_COUNT + UPPERCASE_A_ASCII_CODE)
else:
ciphertext += chr((ord(letter) + shift-LOWERCASE_A_ASCII_CODE) % MAX_ALPHABET_COUNT + LOWERCASE_A_ASCII_CODE)
return ciphertext.lower()
def decode(ciphertext, shift=DEFAULT_SHIFT):
return encode(ciphertext, MAX_ALPHABET_COUNT - shift)
import unittest
import pytest
import caesar_cipher
class CaesarCipherTest(unittest.TestCase):
def test_encode_letter_with_default_shift_distance(self):
plaintext = 'a'
ciphertext = 'b'
self.assertEqual(ciphertext, caesar_cipher.encode(plaintext))
def test_decode_letter_with_default_shift_distance(self):
plaintext = 'b'
ciphertext = 'a'
self.assertEqual(ciphertext, caesar_cipher.decode(plaintext))
def test_encode_wraps_z_to_a(self):
plaintext = 'z'
ciphertext = 'a'
self.assertEqual(ciphertext, caesar_cipher.encode(plaintext))
def test_decode_wraps_a_to_z(self):
plaintext = 'a'
ciphertext = 'z'
self.assertEqual(ciphertext, caesar_cipher.decode(plaintext))
def test_encode_string_with_default_shift_distance(self):
plaintext = 'wxyzabcd'
ciphertext = 'xyzabcde'
self.assertEqual(ciphertext, caesar_cipher.encode(plaintext))
def test_decode_string_with_default_shift_distance(self):
plaintext = 'xyzabcde'
ciphertext = 'wxyzabcd'
self.assertEqual(ciphertext, caesar_cipher.decode(plaintext))
def test_encode_with_10_shift_distance(self):
plaintext = 'wxyzabcd'
ciphertext = 'ghijklmn'
self.assertEqual(ciphertext, caesar_cipher.encode(plaintext, 10))
def test_decode_with_10_shift_distance(self):
plaintext = 'ghijklmn'
ciphertext = 'wxyzabcd'
self.assertEqual(ciphertext, caesar_cipher.decode(plaintext, 10))
def test_encode_with_26_shift_distance(self):
plaintext = 'abcdefghij'
ciphertext = 'abcdefghij'
self.assertEqual(ciphertext, caesar_cipher.encode(plaintext, 26))
def test_decode_with_26_shift_distance(self):
plaintext = 'klmnopqrst'
ciphertext = 'klmnopqrst'
self.assertEqual(ciphertext, caesar_cipher.decode(plaintext, 26))
def test_encode_with_27_shift_distance(self):
plaintext = 'wxyzabcd'
ciphertext = 'xyzabcde'
self.assertEqual(ciphertext, caesar_cipher.encode(plaintext, 27))
def test_decode_with_27_shift_distance(self):
plaintext = 'xyzabcde'
ciphertext = 'wxyzabcd'
self.assertEqual(ciphertext, caesar_cipher.decode(plaintext, 27))
def test_encode_always_returns_downcase_string(self):
plaintext = 'AbCdEfGhIj'
ciphertext = 'bcdefghijk'
self.assertEqual(ciphertext, caesar_cipher.encode(plaintext))
def test_decode_always_returns_downcase_string(self):
plaintext = 'BcDeFgHiJk'
ciphertext = 'abcdefghij'
self.assertEqual(ciphertext, caesar_cipher.decode(plaintext))
# pylint: disable=no-self-use
def test_encode_raise_error_if_non_letter_characters(self):
plaintext = 'az4'
with pytest.raises(Exception):
caesar_cipher.encode(plaintext)
# pylint: disable=no-self-use
def test_decode_raise_error_if_non_letter_characters(self):
plaintext = 'az4'
with pytest.raises(Exception):
caesar_cipher.decode(plaintext)
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment