Caesar Cipher [The Odin Project-Javascript Exercise]

Very new to coding, so please don't bully me.

Implement the legendary caesar cipher:

In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence.

Question: Write a function that takes a string to be encoded and a shift factor and then returns the encoded string:

caesar('A', 1) // simply shifts the letter by 1: returns 'B' the cipher should retain capitalization:

caesar('Hey', 5) // returns 'Mjd; should not shift punctuation:

caesar('Hello, World!', 5) //returns 'Mjqqt, Btwqi!' the shift should wrap around the alphabet:

caesar('Z', 1) // returns 'A' negative numbers should work as well:

caesar('Mjqqt, Btwqi!', -5) // returns 'Hello, World!'

My Solution:

function caesar(string, num) {
let arr = [];
for(let i=0;i<string.length;i++)
{if(!(/[a-zA-Z]/.test(string[i])))
{arr[i]=string[i]; continue;}
let n = string.charCodeAt(i) + num;
if (string[i] == string[i].toLowerCase())
{if(n>122)
{while(n>122)
{n-=26;}}
else
{while(n<97)
{n+=26;}
}
}
else
{if(n>90)
{while(n>90)
{n-=26;}
}
else
{while(n<65)
{n+=26;}
}
}
arr[i]=String.fromCharCode(n);
}
console.log(arr.join(''));
}
caesar("Hello, World!", 2);
caesar("Hello, World!", 75);


The code is working perfectly as per requirement, but please help me with a better solution if possible.

And if you do, please use comments to extensively explain the working process, as I'm quite the noob.

• Welcome to code review. We can't provide alternate code solutions, we do review the code and make comments. May 29, 2020 at 0:22
• @pacmaninbw Okay, then. Thank you for your time. :) May 29, 2020 at 2:36

1. you have an alphabet of 26 letters, so if the shifting operation is limited to a 26 characters range you can use the mod operation %26 to determine the final position.
2. you can have a shift negative operation num (ex. -5), for a 26 set of elements shift this is equal to a positive shift of Math.abs(26 - Math.abs(num)) , so for 5 the positive shift is 21.

So if you have a c character and you want to obtain the ascii code of the corresponding shifted char of num positions you can obtain it in the following way:

const start = c === c.toLowerCase() ? 'a'.charCodeAt(0) : 'A'.charCodeAt(0);
const diff = c.charCodeAt(0) - start;
const sh = num >= 0 ? diff + num : diff + Math.abs(26 - Math.abs(num));
const code = sh % 26 + start;


The first line returns the ascii code of 'a' or 'A' depending if the char c is lowercase or uppercase called start, the second gives you the difference between c and start, the last two lines calculate the code of the shifted corresponding character.

After your function can be rewritten in the following way:

'use strict';

function caesar(str, num) {
const arr = [];
const re = /[a-zA-Z]/;
for (const c of str) {
if (re.test(c)) {
const start = c === c.toLowerCase() ? 'a'.charCodeAt(0) : 'A'.charCodeAt(0);
const diff = c.charCodeAt(0) - start;
const sh = num >= 0 ? diff + num : diff + Math.abs(26 - Math.abs(num));
const code = sh % 26 + start;
arr.push(String.fromCharCode(code));
} else {
arr.push(c);
}
}

return arr.join('');
}


I set arr and regex as const and instead of iterate over string using the index, I preferred the for ... of construct.

Note: I'm a javascript beginner too, so every suggestion to improve my code as for the original question is highly appreciated.

• Yes yes, stupid me totally forgot about absolute value function. And yes, using ternary operator does help a lot in solidifying the code and making it more readable. Thank you for the help. Certainly appreciate it. May 29, 2020 at 12:41
• @AdilAhmed You are welcome. May 29, 2020 at 15:42
• Given you stated: “every suggestion to improve my code as for the original question is highly appreciated.” Feel free to create a new question, linking to this post, and use the tag rags-to-riches Feb 25, 2021 at 7:44
• @SᴀᴍOnᴇᴌᴀ Thank you for your suggestion and for the link, I was not aware about the rags-to-riches tag. Feb 25, 2021 at 8:05