DEV Community

Kiran Kamath
Kiran Kamath

Posted on

Caesar's Cipher (FreeCode Camp Solution)

I recently came across a free code camp problem while solving JavaScript Algorithms and Data Structures certification.

*Problem Statement *:

One of the simplest and most widely known ciphers is a Caesar cipher, also known as a shift cipher. In a shift cipher the meanings of the letters are shifted by some set amount.

A common modern use is the ROT13 cipher, where the values of the letters are shifted by 13 places. Thus A โ†” N, B โ†” O and so on.

Write a function which takes a ROT13 encoded string as input and returns a decoded string.

All letters will be uppercase. Do not transform any non-alphabetic character (i.e. spaces, punctuation), but do pass them on.

Example : rot13("SERR PBQR PNZC") should decode to the string FREE CODE CAMP

Solution :

  1. Take an empty array & store the string passed as arguments by using String split method.
    example : let str = "An Apple"; str.split(''); this will give the result as ['A', 'n', ' ', 'A', 'p', 'p', 'l', 'e'];

  2. Iterate the array using for loop

  3. Inside the loop , take the ASCII char code of the first index and store it in a variable.

  4. Check if the ASCII value lies between 65 and 90 i.e Capital alphabets.

  5. If condition is true , check if ASCII value is greater than 77 i.e greater than 'M' , if it is true then subtract 13 from the ascii value , else if it is less than 77 than add 13 to the ascii value.

  6. Now we need to replace character at that index with the corresponding new ASCII code obtained from step 5 using splice and String.fromCharCode

  7. After the entire loop is completed we need to join the array using the join method.

Check out the final code below.

function rot13(str) {
  let charCode = 0;
  let strArr = [];
  strArr = str.split(""); // split the string into array
  for (let i = 0; i < strArr.length; i++) {
    charCode = strArr[i].charCodeAt();
    if (charCode >= 65 && charCode <= 90) {
      if (charCode > 77) {
        charCode = charCode - 13;
      }
      else {
        charCode = charCode + 13;
      }

      strArr.splice(i,1,String.fromCharCode(charCode));
    }
  }
  return strArr.join('');
}

rot13("SERR PBQR PNZC");
Enter fullscreen mode Exit fullscreen mode

Here is the link for the problem : https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/caesars-cipher

Latest comments (5)

Collapse
 
saraarian profile image
saraarian

Hi,
I wrote the code in a different way, but it works for some letters in a string and does not for others.
function rot13(str) {
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";

let regex= /\w/;
for (let i=0; i<str.length; i++){
if(regex.test(str[i])){
let myIndex= (alphabet.indexOf(str[i]))+13

str = str.replace(str[i] , alphabet[myIndex]);
Enter fullscreen mode Exit fullscreen mode

}

}

return str;
}

for example console.log(rot13("SERR CVMMN!")) would return FEER PIZZA! instead of FREE PIZZA!

can you explain why? of course it is not too much to ask.
Thanks
Sara

Collapse
 
dailydevtips1 profile image
Chris Bongers

Great solution already!
Other than Alex his comments below and the one he posted on my one this is great!.

Maybe you could try and make it dynamic so the 13 is an optional fix?

Collapse
 
kirankamath96 profile image
Kiran Kamath

Yeah Chris , I took 13 as it is the half of 26 , and accordingly I can write the logic.

Collapse
 
lexlohr profile image
Alex Lohr • Edited

If you are already using a for-loop instead of string.replace to iterate over the string, you can also use str.charCodeAt(i), so you don't have to convert the string to array first.

Then, you can use const inside the for loop instead of let outside. If you don't plan to replace the array, you can and should directly assign it (though it's not necessary).

Other than that, check my comment to Chris' post. ASCII characters are organized in a useful manner, something you can use.

Collapse
 
kirankamath96 profile image
Kiran Kamath

Thanks Alex . I will try that