# freeCodeCamp Challenge Guide: Caesars Cipher

freeCodeCamp Challenge Guide: Caesars Cipher
0

I did the exact same thing

I asked a question about going a different route than whatβs suggested, I hope people respond.

Honestly I make more sense out of the solution that you and I came up with, but thatβs only because the suggested methods were unfamiliar and I didnβt dive into learning about them.

Technically weβre not wrong, but Iβm not sure which solution is faster / more practical (I think ours lol) / etc.

Cheers to solving it our own way

2 Likes

Hi, hereβs my solution:

``````function rot13(str) { // LBH QVQ VG!
var utf = [];
var retour = [];
// push unicode to utf-array
for ( var i = 0; i < str.length; i++) {
utf.push(str.charCodeAt(i));
}
// convert utf array from ciphertext
for (var j = 0; j < str.length; j++) {
if(utf[j] >= 78)
utf[j] -= 13;
else if(utf[j] >= 65)
utf[j] += 13;
else
utf[j] += 0;
//push calculated solution to retour-array
retour.push(String.fromCharCode(utf[j]));
}
return retour.join("");
}

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

My current working solution. If anyone has suggestions on how I can tighten this up I would appreciate it :

``````function rot13(str) {
var arr = str.split('');
var unicode = [];
var shifted = [];
for(var i = 0; i < arr.length; i++) {
var toUnicode = arr[i].charCodeAt(arr[i]);
unicode.push(toUnicode);
}
for(var j = 0; j < unicode.length; j++) {
if(unicode[j] == 32) {
shifted.push(unicode[j]);
} else if(unicode[j] == 32) {
shifted.push(unicode[j]);
} else if(unicode[j] == 33) {
shifted.push(unicode[j]);
} else if(unicode[j] == 63) {
shifted.push(unicode[j]);
} else if(unicode[j] == 46) {
shifted.push(unicode[j]);
} else if (unicode[j] >= 65 && unicode[j] <= 77 ) {
shifted.push(unicode[j] + 13);
} else {
shifted.push(unicode[j] - 13);
}
}
var result = shifted.map(function(item) { return String.fromCharCode(item) }).join('');

return result;

}
``````

`rot13("SERR PBQR PNZC");`

1 Like

This is my solution, could not find any bugs

```
``` function rot13(str) { // LBH QVQ VG!
console.log(String.fromCharCode(34));
result = ββ;
code = 0;
for (i=0; i<str.length; i++)  {
code = str[i].charCodeAt(0);
if (code >= 65 && code <= 77) {
result += (String.fromCharCode(code+13));
} else if (code >= 78 && code <= 90) {
result += (String.fromCharCode(code-13));
} else {
result += str[i];
}
}
return result;
}
// Change the inputs below to test
rot13(βNF GNIR ZLYVHβ);
``````
1 Like

Using replace:

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

function replacer(match, p1) {
var idx = match.charCodeAt(0);
return idx > 90 - 13 ? String.fromCharCode(idx - 26 + 13) : String.fromCharCode(idx + 13);
}
return str.replace(/[A-Z]/g, replacer);
}

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

I took a more βfunβ approach to the problem; once I realised the basic algorithm behind it, I decided to write it using everyoneβs favourite bit-wise conditional operator and clean it up a little.

Just to ensure no-one uses this type of approach in the workplace, Iβm going to say NEVER use chains of ternary operators because it can be hard to read for other programmers & slow down your program, which in responsive JavaScript webpages or real-time systems, is bad.

2 Likes

here it is with a switch statement:

function rot13(str) {
var cipher =str.split(""); //first you turn the string into an array
for (i=0;i<cipher.length;i++){ //make a for loop that runs through the whole array
switch(cipher[i]) { //you need a switch statement for every letter.
case βAβ:
cipher[i]= βNβ;
break;
case βBβ:
cipher[i]= βOβ;
break;
case βCβ:
cipher[i]= βPβ;
break;
case βDβ:
cipher[i]= βQβ;
break;
case βEβ:
cipher[i]= βRβ;
break;
case βFβ:
cipher[i]= βSβ;
break;
case βGβ:
cipher[i]= βTβ;
break;
case βHβ:
cipher[i]= βUβ;
break;
case βIβ:
cipher[i]= βVβ;
break;
case βJβ:
cipher[i]= βWβ;
break;
case βKβ:
cipher[i]= βXβ;
break;
case βLβ:
cipher[i]= βYβ;
break;
case βMβ:
cipher[i]= βZβ;
break;
case βNβ:
cipher[i]= βAβ;
break;
case βOβ:
cipher[i]= βBβ;
break;
case βPβ:
cipher[i]= βCβ;
break;
case βQβ:
cipher[i]= βDβ;
break;
case βRβ:
cipher[i]= βEβ;
break;
case βSβ:
cipher[i]= βFβ;
break;
case βTβ:
cipher[i]= βGβ;
break;
case βUβ:
cipher[i]= βHβ;
break;
case βVβ:
cipher[i]= βIβ;
break;
case βWβ:
cipher[i]= βJβ;
break;
case βXβ:
cipher[i]= βKβ;
break;
case βYβ:
cipher[i]= βLβ;
break;
case βZβ:
cipher[i]= βMβ;
break;
default:
cipher[i]=cipher[i]; //default (not A-Z) return same character
}

}
decoded= cipher.join(""); //now turn the array into a string
return decoded; //and there it is!
}

// Change the inputs below to test
rot13(βSERR PBQR PNZCβ);

1 Like

here it is with a switch statement:

function rot13(str) {
var cipher =str.split(""); //first you turn the string into an array
for (i=0;i<cipher.length;i++){ //make a for loop that runs through the whole array
switch(cipher[i]) { //you need a switch casefor every letter.
case βAβ:
cipher[i]= βNβ;
break;
case βBβ:
cipher[i]= βOβ;
break;
case βCβ:
cipher[i]= βPβ;
break;
case βDβ:
cipher[i]= βQβ;
break;
case βEβ:
cipher[i]= βRβ;
break;
case βFβ:
cipher[i]= βSβ;
break;
case βGβ:
cipher[i]= βTβ;
break;
case βHβ:
cipher[i]= βUβ;
break;
case βIβ:
cipher[i]= βVβ;
break;
case βJβ:
cipher[i]= βWβ;
break;
case βKβ:
cipher[i]= βXβ;
break;
case βLβ:
cipher[i]= βYβ;
break;
case βMβ:
cipher[i]= βZβ;
break;
case βNβ:
cipher[i]= βAβ;
break;
case βOβ:
cipher[i]= βBβ;
break;
case βPβ:
cipher[i]= βCβ;
break;
case βQβ:
cipher[i]= βDβ;
break;
case βRβ:
cipher[i]= βEβ;
break;
case βSβ:
cipher[i]= βFβ;
break;
case βTβ:
cipher[i]= βGβ;
break;
case βUβ:
cipher[i]= βHβ;
break;
case βVβ:
cipher[i]= βIβ;
break;
case βWβ:
cipher[i]= βJβ;
break;
case βXβ:
cipher[i]= βKβ;
break;
case βYβ:
cipher[i]= βLβ;
break;
case βZβ:
cipher[i]= βMβ;
break;
default:
cipher[i]=cipher[i]; //default (not A-Z) return same character
}

}
decoded= cipher.join(""); //now turn the array into a string
return decoded; //and there it is!

3 Likes

hi,

I immediately thought of the function βreplace ()β associated with a βregexβ. But I found it difficult to find the logic of β+13β or β-13β until I found a table that showed that the letters ranged from βA = 65β to βZ = 90β.

So, my solution:

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

function remplace(letter) {
var mod = letter.charCodeAt();
var plus;

``````if(mod > 77) {
plus = - 13;
}

if(mod <= 77) {
plus = + 13;
}

return String.fromCharCode(mod + plus);
``````

}

return str.replace(/[A-Z]/g, remplace);
}

// Change the inputs below to test
rot13(βLBH QVQ VG!β);

``````function rot13(str) { // LBH QVQ VG!
var n=str.split(''),m="";
for(var i=0;i<n.length;i++){
var x = str.charCodeAt(i);
if(x < 65 || x>90){
m+=String.fromCharCode(x);
} else if(x < 78){
m+=String.fromCharCode(x + 13);
} else {
m+=String.fromCharCode(x - 13);
}
}
return m;
}
``````

I did it with Regexp instead of charcode checks. Basically the same though.

``````  function rot13(str) {
var uniStr = [];
var decode = "";
for (var i = 0; i < str.length; i++) {
if (str[i] == str[i].match(/[a-m]/gi)) {
uniStr.push(str.charCodeAt(i) + 13);
} else if (str[i] == str[i].match(/[n-z]/gi)) {
uniStr.push(str.charCodeAt(i) - 13);
} else {
uniStr.push(str.charCodeAt(i));
}
}
for (var j = 0; j < uniStr.length; j++) {
decode = decode.concat(String.fromCharCode(uniStr[j]));
}
return decode;
}``````
1 Like

I figured out an alternative solution for the problem :

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

var newStr = [];

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

``````if (str.charCodeAt(i) < 65 || str.charCodeAt(i) > 90) {

newStr[i] = str[i];

} else  {

if (str.charCodeAt(i) + 13 <= 90) {

newStr[i] = String.fromCharCode(str.charCodeAt(i) + 13);
``````

} else {

``````      newStr[i] = String.fromCharCode(str.charCodeAt(i) - 13);
``````

}

``````}
``````

}

return newStr.join(ββ);
}

// Change the inputs below to test
rot13(βSERR CVMMN!β);

It was very hard, I needed to read and study a lot! kkkkkkkkk

function rot13(str) { // LBH QVQ VG!
var newStr = [];
for(var i=0; i<str.length; i++){
if(str.charCodeAt(i)<65 || str.charCodeAt(i)>90){
newStr.push(str[i]);
} else if (str.charCodeAt(i)>77){ // 90 -13
newStr.push(String.fromCharCode(str.charCodeAt(i)-13));
} else { // 65 +13
newStr.push(String.fromCharCode(str.charCodeAt(i)+13));
}
}
return newStr.join(ββ);
}

// Change the inputs below to test
rot13(βSERR PBQR PNZCβ);

2 Likes

Hello, my solution is as follows. I have converted into an array to be able to use map first.

``````function rot13(str) { // LBH QVQ VG!
return Array.prototype.map.call(str, function(x){
return (x.charCodeAt(0) >= 65) ?
(x.charCodeAt(0) < 78 ) ?
String.fromCharCode(x.charCodeAt(0)+13) : (x.charCodeAt(0) <= 90 ) ?
String.fromCharCode(x.charCodeAt(0)-13) : x : x;
}).join('');

}

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

I am not proud of my solution at all, but it works

``````function rot13(str) {
let temp = '';
for(let i = 0; i < str.length; i++) {
let charCodeLetter = str[i].charCodeAt();
if(charCodeLetter < 65 || charCodeLetter > 90) {
let encodedLetter = String.fromCharCode(charCodeLetter);
temp += encodedLetter;
} else {
if(charCodeLetter > 77) {
charCodeLetter = charCodeLetter - 13;
} else if (charCodeLetter < 78) {
charCodeLetter = charCodeLetter + 13;
}
encodedLetter = String.fromCharCode(charCodeLetter);
temp += encodedLetter;
}
}
return temp;
}
rot13("SERR YBIR?");
``````

another solution, this time more fancy

``````function rot13(str) {
let chars = str.split('');

return chars.map(char => {
char = char.charCodeAt();

if(char < 78 && char > 64 ) char += 13;
else if (char < 91 && char > 77) char -= 13;

return String.fromCharCode(char);
}).join('');
}

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

hrere is my solution .

```function rot13(str) { var str1=str.split(" β); var t=[]; for(var i=0;i<str1.length;i++) { var r=β"; for(var j=0;j<str1[i].length;j++) { var c=0; c=str1[i].charCodeAt(j); if(c>64&&c<78) c+=13; else if(c>=78&&c<92) c-=13; r+=String.fromCharCodeΒ©; } t[i]=r; } return t.join(" "); } rot13(βGUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.β);```

###hereβs a refactored solution:

function rot13(str){
return String.fromCharCode((c.charCodeAt() % 26) + 65);
} else {
return c;
}
}).join(ββ);
}

I annotated my code notes so its hopefully easy to understand

explanations below it

``````function rot13(str) {
//Convert to array simpler to calculate no string immutability
var newArr = str.split('');

//Loop each array val apply decrypt func
for (let i =0; i<newArr.length;i++){
newArr[i]= shiftValues(newArr[i]);
}

return newArr.join('');

//---------------------------------------
//Decrypt function
function shiftValues(val){

//Ignore spaces
if (val.match(/\W/i)) {
return val;
}

//Define shift
var shift=13;

//Convert to ASCII values
val=val.charCodeAt(0);

//Equalize to base 0 index, 'A' of 65 is 0
val=val-65;

//If val-shift is negative, add 26 so it counts backwards
if ((val-shift)>=0){
val=val-shift;
} else {
val=val-shift+26;
}

//Unequalize it now
val=val+65;

//Convert to Character
val = String.fromCharCode(val);

return val;
}
//-------------------------------------

}

rot13("SERR PBQR PNZC");
``````

brief Explanation of main program:

• Convert to an array so its easy to work with
• Loop through each value in array
• Use custom function to do decrypting of each letter
• Combine resulting array into string
• Output results

Explanation of function: (as it loops each value in array)

• Ignore any spaces using regex
• Convert to ASCII number
• Make 65 so now it index0 (A=0, B=1, C=2, D=3β¦Y=24, Z=25)
• Do the decryption 13 shift more on this in a bit
• Unmake 65 so no longer index0
• Convert back to char
• Send char back

### explaining complicated part:

[spoiler]

Explanation of the more on this in a bit part:

I use shift = 14 as example, since its less confusing than 13 example

• Say we have βLβ. Its the 11th letter in alphabet (where βAβ is 0 index)
• Now letβs say our shift is 14.
• 11-14 = -3. We have a negative number. Now what?
• What value is it supposed to be?
• Its supposed to be βXβ , or 3 positions away from the end of alphabet,
• X = 26-3

So we know βLβ with a shift of 14 is supposed to be βXβ

• βXβ has a value of 23.
• βLβ has a value of 11
• The shift is 14

So how do you get from a value of 11 to 23?

• 11 - 14 + ??? = 23
• ??? is 26
• Thereβs 26 letters in the alphabet

In summary;

If your going to have a negative number when you do your shift add 26. Otherwise, leave it as is

Thereβs other solutions around this using modulo operators `%`, but I didnβt use that though [/spoiler]

1 Like

my solution I do not know if this is true in every case or not?

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

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

st+=String.fromCharCode(str.charCodeAt(i)<65?str.charCodeAt(i):str.charCodeAt(i)+13>90?str.charCodeAt(i)-13:str.charCodeAt(i)+13);
}
return st;
}``````

abusing map()

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

var arr = str.split(" ");

var split = arr.map(function (x){

``````return x.split('').map(function (y){
return y.charCodeAt(x);
``````

});
});

var convert = split.map(function (x){
return x.map(function (y){
if (y < 65 || y > 90){
return String.fromCharCode(y);
}
else if (y < 78) {
return String.fromCharCode (y + 13);
}
else {
return String.fromCharCode (y - 13);
}

});
});

return convert.map(function (x){
return x.join(ββ);
}).join(" ");

}

// Change the inputs below to test
rot13(βGUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.β);