Caesar Cipher Encryptor

Problem

Given lowercase letters and an integer that represents a key, return a new string created by shifting every letter in the input string by k positions in the alphabet, where k is the key.

important

Letters should "wrap" around the alphabet.

i.e. The letter z shifted by one returns the letter a.


Code

Python

def caesarCipherEncryptor(string, key):
newLetters = []
newKey = key % 26
for letter in string:
newLetters.append(getNewLetter(letter, newKey))
return "".join(newLetters)
def getNewLetter(letter, key):
newLetterCode = ord(letter) + key
return chr(newLetterCode) if newLetterCode <= 122 else chr(96 + newLetterCode % 122)

JavaScript

function caesarCipherEncryptor(string, key) {
const newLetters = [];
const newKey = key % 26;
for (const letter of string) {
newLetters.push(getNewLetter(letter, newKey));
}
return newLetters.join('');
}
function getNewLetter(letter, key) {
const newLetterCode = letter.charCodeAt() + key;
return newLetterCode <= 122 ? String.fromCharCode(newLetterCode) : String.fromCharCode(96 + (newLetterCode % 122));
}
exports.caesarCipherEncryptor = caesarCipherEncryptor;

TypeScript

export function caesarCipherEncryptor(string: string, key: number) {
const newLetters = [];
const newKey = key % 26;
for (const letter of string) {
newLetters.push(getNewLetter(letter, newKey));
}
return newLetters.join('');
}
function getNewLetter(letter: string, key: number) {
const newLetterCode = letter.charCodeAt(0) + key;
return newLetterCode <= 122 ? String.fromCharCode(newLetterCode) : String.fromCharCode(96 + (newLetterCode % 122));
}

Java

class Program {
public static String caesarCypherEncryptor(String str, int key) {
char[] newLetters = new char[str.length()];
int newKey = key % 26;
for (int i = 0; i < str.length(); i++) {
newLetters[i] = getNewLetter(str.charAt(i), newKey);
}
return new String(newLetters);
}
public static char getNewLetter(char letter, int key) {
int newLetterCode = letter + key;
return newLetterCode <= 122 ? (char) newLetterCode : (char) (96 + newLetterCode % 122);
}
}

C++

#include <vector>
#include <numeric>
using namespace std;
char getNewLetter(char letter, int key);
string caesarCypherEncryptor(string str, int key) {
vector<char> newLetters;
int newKey = key % 26;
for (int i = 0; i < str.length(); i++) {
newLetters.push_back(getNewLetter(str[i], newKey));
}
return string(newLetters.begin(), newLetters.end());
}
char getNewLetter(char letter, int key) {
int newLetterCode = letter + key;
return newLetterCode <= 122 ? newLetterCode : 96 + newLetterCode % 122;
}

Space-Time Complexity

TimeSpace
WorseO(n)O(n)

Where n is the length of the input string


Notes

Letter -> Unicode -> Character Approach

solution 1

Create an array to contain all of our new letters, and iterate through the input string

At each letter, apply algorithm to shift letter by the key, get a new letter, and then throw that new letter into return array

Once you're done building the array, you join it all together into a string, and return that string

nLC = ord(letter) + key
if nLC <= 122:
return chr(nLC)
else:
return chr(96 + nLC % 122)

e.g. Let's say we do z + 2, which is 122 + 2

We divide 124 by 122 and get the remainder (mod %), which is going to be 2. Then, we add this to 96 which is the unicode that comes right before a

What happens if the key is a big number?

e.g. key = 54

You would end up calling the chr() on something that's greater than 122. And, that's not what you want. You want to wrap around the alphabet

So, what we can do is that at the very beginning of our algorithm, instead of dealing with a big number like 54, what we can do is say key = key % 26, because 26 is the number of letters in our alphabet

By doing this, we don't end up in the situation where our key is outside of our alphabet size

Alphabet Array Approach

solution 2

Create an array with all the letters in the alphabet, the index that each letter is at is their corresponding "unicode" value

e.g. the letter a would be at index 0, and the letter z would be at index 25, and that would be their corresponding code value

i.e. instead of a => 97 it'll be a => 0, and instead of z => 122 it'll be z => 25

Our algorithm would then change to:

nLC = al_arr.index(letter) + key
if nLC <= 25:
return al_arr[nLC]
else:
return al_arr[-1 + nLC % 25]