 # Caesars Cipher, Works but I wanted to to it better! (Spoilers)

This code works and I’ve tried to explain my thinking, but I really wanted to use a regular expression to match all the Capital letters, but I struggled to get it to work.

function rot13(str) { // LBH QVQ VG!

``````var code = []; // create an empty array to hold the code numbers
var newString = []; // create an empty array to hold the decoded string
``````
``````//iterate through the string and push its
//charCode to the code array
for (var i = 0; i < str.length; i++) {
``````
``````    code.push(str.charCodeAt([i]));
}
//console.log(code);
``````
``````// function to map each value of code to a new array
// codeRot13, adding 13 to each number
var codeRot13 = code.map(function (val) {
``````
``````    return val + 13;
});
``````
``````//console.log(codeRot13);
``````
``````//Iterate though codeRote13 and if the value is above 90(z) return
// to 65(a) and add the balance
//else if that results in going over 78 (A+13) remove the 13.
for (var j = 0; j < codeRot13.length; j++) {
``````
``````    if (codeRot13[j] > 90) {
codeRot13[j] = 65 + (codeRot13[j] - 91);
} else if (codeRot13[j] < 78) {
``````
``````        codeRot13[j] = codeRot13[j] - 13;
}
}
``````
``````//console.log(codeRot13);
``````
``````//Turn it back to a string
for (var k = 0; k < codeRot13.length; k++) {
``````
``````    newString.push(String.fromCharCode(codeRot13[k]));
``````
``````}
``````
``````newString = newString.join('');
``````
``````//console.log(newString);
``````
``````return newString;
``````

}

Any help on how I could do this and still understand what going on would be appreciated. Thanks

Here is my attempt:

``````function rot13(str) {
var result = [];

str.split('').forEach(function(i) {
if (/[A-Z]/.test(i)) {
i = (String.fromCharCode(65 + (i.charCodeAt(0) - 65 + 13) % 26));
}
result.push(i);
});

return result.join('');
}
``````

I split string to get an array and then loop through that array and test each element (character).

If it is a capital letter do the conversion by getting that letters position in alphabet, adding 13 (ROT number) and applying modulus of 26 (number of letters in alphabet) so if the number is bigger than 26 it loops back to the beginning.

Push `i` to the `result` array;

Join `result` array together to get string and return resulting string.

Or you can write it in one line using `map()` and ES6 (not very readable, but looks cool):

``````function rot13(str) {
return str.split('').map(i => i = /[A-Z]/.test(i) ? (String.fromCharCode(65 + (i.charCodeAt(0) - 65 + 13) % 26)) : i).join('');
}
``````
1 Like

Wow, both your examples are so fantastic, admittedly I find the first one easier to follow, but I agree the second example is so cool.

Thank you for taking the time to show me your code, I still have a lot to learn, but seeing great code really helps I come from a more PHP back ground and this was my shot at this, quite simple although i liked Jenovs own pretty neat.

``````function rot13(str) {

// Ensure string is upper case as upper case and lower case have different unicode value
str.toUpperCase();

var newStr = '';
var letter;

for ( var i = 0; i < str.length; i++ ) {

// Get unicode value before decripted
var result = str.charCodeAt(i);

if ( result <= 77 && result >= 65 ) {

// Get Decripted letter
letter = String.fromCharCode(result + 13);

} else if ( result > 77 && result <= 90 ) {

// Get decripted letter
letter = String.fromCharCode(result - 13);

} else {

letter = String.fromCharCode(result);

}

newStr = newStr + letter;

}

return newStr;

}``````

Thanks, That’s a neat bit of code and very easy to understand.

Here is my solution:

function rot13(str) { // LBH QVQ VG!
var arr = [];
for (var i = 0; i < str.length; i++) {
var num = str.charCodeAt(i);
arr.push(num);
}

for (var j = 0; j < arr.length; j++) {
if ( arr[j] >= 65 && arr[j] <= 77 ) {
arr[j] = arr[j] + 13;
}
else if (arr[j] >= 78 && arr[j] <= 90) {
arr[j] = arr[j] - 13;
}
}
for (var k = 0; k < arr.length; k++) {
var decode = String.fromCharCode(arr[k]);
}

}

Yeah, I know what you are talk about. Personally, I try to use all the JS functions as much as possible.

Here is my solution. I use repl.it to have a working example of the algorithm.

``````/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SOLUTION CODE
https://repl.it/E1dg/3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
function rot13(str) { // LBH QVQ VG!
// Split str into a character array
return str.split('')
// Iterate over each character in the array
// c = current element
// i = current index
.map(function(c, i) {
// Convert char to a character code
var strCode = str.charCodeAt(i);
// Checks if character lies between A - M
if (strCode >= 65 && strCode <= 77) {
return String.fromCharCode((strCode) + 13);
// Checks if character lies betweenm N - Z
} else if (strCode >= 78 && strCode <= 90) {
return String.fromCharCode((strCode) - 13);
// Return character
} else {
return c;
}
//console.log("i: " + i + " : " + c + " : " + strCode + " : " + strChange);
}).join(''); // Rejoin the array into a string
}

// Change the inputs below to test
rot13("SERR PBQR PNZC");
``````

This is what I tried…

``````function rot13(str) {
var num = 0;
var myString = "";
for (var i = 0; i < str.length; i++) {
num = str.charCodeAt(i);
if (num >= 65) {
num += 13;
}
if (num > 90) {
num -= 26;
}
myString += String.fromCharCode(num);
}
return myString;
}
``````
1 Like

This took me a while:

``````function rot13(str) { // LBH QVQ VG!

var strArray = str.split("");
strArray = strArray.map(function(letter){
return letter.charCodeAt();

});

strArray = strArray.map(function(code1){
if (code1 >= 65+13 && code1 <= 90) {
code1 -=13;
}
else if (code1 < 65+13 && code1 >= 65) {
code1 += 13;
}
return String.fromCharCode(code1);
});
return strArray.join("");

}``````

After finally getting this algo working with some hard-coded exceptions for the punctuation, that ES6 solution is blowing my brain apart. SO COOL.

Here’s my solution using a slightly different method

``````function rot13(str) {
return str.replace(/[A-Z]/ig, c => (
String.fromCharCode(c.charCodeAt() + (/[A-M]/.test(c) ? 13 : -13))
));
}
``````
4 Likes

function rot13(str) { // LBH QVQ VG!

var n ,val;
var ch =0 ;

var decodede_str=’’;
var encry_str =str ;
// encry_str = str.split(’’);
var len = encry_str.length;

for(var i=0 ; i< len ;i++ ){

n = encry_str.charCodeAt(i);

if(n < 78 && n>=65){
ch = n+13;}
else
if( n >=78 && n<91)
ch = n-13;
else
if(n>91){
ch = 65 + (n-91);}
else{
ch = n;
}

val = String.fromCharCode(ch);
decodede_str = decodede_str + val;
console.log(decodede_str);
}
return decodede_str;

}
// Change the inputs below to test
rot13(“GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.”);

Here’s my solution

``````
function rot13(str) { // LBH QVQ VG!

function decode(val){
// check if character is between A-Z
if (val>='A' && val<='Z') {
return val.charCodeAt() > (64+13) ? String.fromCharCode(val.charCodeAt()-13) : String.fromCharCode(val.charCodeAt()+13);
} else {
// not A-Z; so return original character
return val;
}
}

return str.split('').map( decode ).join('');

}

// Change the inputs below to test
rot13("GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.")
``````

I think, this is the simplest solution. I understand others have developed some really cool/advanced ones, but this is so easy to understand. Great job What is `test(c)` ?

whew I finally made it through the basic algos. Here is what I came up with for this last one
I like my version because 1) you can clearly see the relationship between input and output and 2) it is easy to swap out the cipher array for another (such as [‘t’, ‘h’, ‘e’, ‘q’, ‘u’, ‘i’ ,‘c’ ,‘k’, ‘b’, 'r ', ‘o’, ‘w’ ,‘n’, ‘f’, ‘o’ , ‘x’…]
function rot13(str) {
var abc = [‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’ ];
var nop = [ ‘N’, ‘O’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’];
var newStr = “”;

for (var i = 0; i < str.length; i++) {

``````if (abc.indexOf(str[i]) < 0) { // leaves symbols in
newStr += str[i];
} else {

newStr += nop[abc.indexOf(str[i])];
}
``````

}
return newStr;
}

.test() is a method on the RegExp object that checks if a value passes the regex test and returns a boolean. /[A-M]/ is a regex literal, so this is checking that the character, c, in the arrow function is between the letters A-M.