Created
May 17, 2019 20:24
-
-
Save j3speaks/b1885ffa42c1d46679e95471d2ba6f16 to your computer and use it in GitHub Desktop.
Caesar Cipher written in Python
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
# 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) |
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
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