Caesar's Cipher Refactoring Help

I finally figured out how to solve Caesar’s Cipher, but I would appreciate some guidance in how to make my code better and more efficient.

Here is my code:

function rot13(str) { // LBH QVQ VG!
  var willBeStr = [];
  for(var i=0; i < str.length; i++) {
    if(str.charCodeAt(i) < 65 || str.charCodeAt(i) > 122 || str.charCodeAt(i) > 90 && str.charCodeAt(i) < 97) {
      willBeStr.push(String.fromCharCode(str.charCodeAt(i)));
    } else if(str.charCodeAt(i) >= 97 && str.charCodeAt(i) <=122) {
      if((str.charCodeAt(i) - 22) > 77) {
        willBeStr.push(String.fromCharCode(str.charCodeAt(i) - 35));
      } else {
        willBeStr.push(String.fromCharCode(str.charCodeAt(i) - 9));
      }
    } else {
      if(str.charCodeAt(i) > 77) {
        willBeStr.push(String.fromCharCode(str.charCodeAt(i) - 13));
      } else {
        willBeStr.push(String.fromCharCode(str.charCodeAt(i) + 13));
      }
    }
  
  
  }
  return willBeStr.join("");
} 

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

One thing you might look into is how you can make use of ‘modular arithmetic’ to make the ‘rotational’ part of the cipher more efficient. It’s the same kind of math that can be used to calculate an arrival time even when a 24-hour clock ‘resets’ to 0 after midnight…

Hi Joel,

Some remarks:

  1. I did mine comparing on letters rather than on their charCode. That makes it easier to read and you don’t have ‘magic’ numbers (who knows the charCodes of the set off the top of their head?).
  2. When you use a RegEx to check for letters and non-letters, you can do away with the long condition in your first if statement.
  3. Like @geligelu said: try to make the comparisons more efficient.

Re 2: if (str[i].match(/[A-Z]/)) { /* it's a letter */ }

1 Like

Some good advice above here. I would add that you are doing a lot of duplicate calls to convert your string to and from charCode. Whenever you repeat yourself a lot in your code you should pause and think about if it’s really necessary.
You might want to think about using a variable to store the converted value in this case.

1 Like

Wow, I did use the regex to find out if it’s a letter and I did use the test ( < ‘N’) to find out if I needed to add or subtract 13, but it never occurred to me to do just a replace. Great idea.

Hello Guys,

I am burning my brain trying to solve this one. I copy and paste my code after a lot of thinking. I think it should work the way it is… but I am almost sure that I am not knowing how to deal with the charcode. I tried to find some cheatcode or something so I could analyze the charcode better.

I am felling stucked in this one now. Just because I couldn’t make the charcode loop or create some equation on it.
If it is the only bad part in my code, please help me understand the charset or how to think about that.

Thanks a lot!

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

  function replacer(X){
   return String.fromCharCode(X.charCodeAt(0));  
  }
  
return str.replace(/[A-Z]/g, replacer);

}

(second response)
reading here I tried to do:

return String.fromCharCode(X.charCodeAt(0) > 13 ? X.charCodeAt(0) - 13 : X.charCodeAt(0) + 13);

and just some letters are wrong. aaaaaaahhhhhhhhhh

(third and last, sorry guys and thanks for the comments above)

return String.fromCharCode(X.charCodeAt(0) > 77 ? X.charCodeAt(0) - 13 : X.charCodeAt(0) + 13);