Software Engineering

How to Solve Caesar Cipher Helper in Python


The challenge

Write a class that, when given a string, will return an uppercase string with each letter shifted forward in the alphabet by however many spots the cipher was initialized to.

Example:

c = CaesarCipher(5); # creates a CipherHelper with a shift of five
c.decode('BFKKQJX') # returns 'WAFFLES'

If something in the string is not in the alphabet (e.g. punctuation, spaces), simply leave it as is.
The shift will always be in the range of [1, 26].

The solution in Python code

Option 1:

from string import maketrans

class CaesarCipher(object):
    def __init__(self, shift):
        self.alpha = "abcdefghijklmnopqrstuvwxyz".upper()
        self.newalpha = self.alpha[shift:] + self.alpha[:shift]

    def encode(self, str):
        t = maketrans(self.alpha, self.newalpha)
        return str.upper().translate(t)

    def decode(self, str):
        t = maketrans(self.newalpha, self.alpha)
        return str.upper().translate(t)

Option 2:

class CaesarCipher(object):
    def __init__(self, shift):
        self.s=shift
        pass;

    def encode(self, str):
        return ''.join(chr((ord(i)+self.s-ord('A'))%26+ord('A')) if i.isalpha() else i for i in str.upper())
        
    def decode(self, str):
        return ''.join(chr((ord(i)-self.s+ord('A'))%26+ord('A')) if i.isalpha() else i for i in str.upper())

Option 3:

class CaesarCipher(object):
    
    def __init__(self, shift):
        abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
        self.enc_dict = dict(zip(abc, abc[shift:] + abc[:shift]))
        self.dec_dict = dict(zip(abc[shift:] + abc[:shift], abc, ))
    
    def encode(self, str):
        return ''.join( self.enc_dict.get(c, c) for c in str.upper() )
    
    def decode(self, str):
        return ''.join( self.dec_dict.get(c, c) for c in str.upper() )

Test cases to validate our solution

test.describe("Testing the CaesarCipher class");
test.it("Shift of 5");
    
c =  CaesarCipher(5);

test.assert_equals(c.encode('WAFFLES'), 'BFKKQJX');
test.assert_equals(c.decode('BFKKQJX'), 'WAFFLES');
test.assert_equals(c.encode("IT'S A SHIFT CIPHER!!"), "NY'X F XMNKY HNUMJW!!");
test.assert_equals(c.decode("NY'X F XMNKY HNUMJW!!"), "IT'S A SHIFT CIPHER!!");

test.it("Shift of 13");

c =  CaesarCipher(13);
test.assert_equals(c.encode('CNAPNXRF'), 'PANCAKES');
test.assert_equals(c.decode('PANCAKES'), 'CNAPNXRF');
test.assert_equals(c.encode('JAVASCRIPT'), 'WNINFPEVCG');
test.assert_equals(c.decode('WNINFPEVCG'), 'JAVASCRIPT');

from random import sample
import string
for i in range(0, 5):
    rs = ''.join(sample(string.punctuation + string.ascii_uppercase, 10));
    test.assert_equals(c.decode(c.encode(rs)), rs);

test.it("Shift of 26");
c = CaesarCipher(26);
    
for i in range(0, 7):
    rs = ''.join(sample(string.punctuation + string.ascii_uppercase, 15));
    test.assert_equals(c.decode(rs), rs);
    test.assert_equals(c.encode(rs), rs);