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);