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 :
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'];Iterate the array using for loop
Inside the loop , take the ASCII char code of the first index and store it in a variable.
Check if the ASCII value lies between 65 and 90 i.e Capital alphabets.
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.
Now we need to replace character at that index with the corresponding new ASCII code obtained from step 5 using splice and String.fromCharCode
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");
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
Top comments (5)
If you are already using a for-loop instead of
string.replace
to iterate over the string, you can also usestr.charCodeAt(i)
, so you don't have to convert the string to array first.Then, you can use
const
inside the for loop instead oflet
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.
Thanks Alex . I will try that
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
}
}
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
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?
Yeah Chris , I took 13 as it is the half of 26 , and accordingly I can write the logic.