Caesars Cipher algorithm - almost got it. What's next?

Hi,

This is my code:

function rot13(str) {

  for (var i = 0; i < str.length; i++) {
    if (str.charCodeAt(i) <= 78 && str.search(/[^A-Za-z\s]/) != -1) {
      str += String.fromCharCode(str.charCodeAt(65 + 13 + 90 - i));
      }
    else if (str.charCodeAt(i) >= 78 && str.search(/[^A-Za-z\s]/) != -1) {
      str += String.fromCharCode(str.charCodeAt(i + 13)
  ));
      }
  }

  return str;

}

rot13("SERR PBQR PNZC");

Now, I think I might have to adjust some of the numbers (65 + 13 + 90 - i) which is why I left them a bit verbose, and maybe deal with the white space in a different way, but I can’t even test it because I cannot alter the values of the string or create a new string (var cache = “”) to hold the incremented values of “i”.

In PythonTutor, the value of “str += …” never changes, and ultimately returns the original string.

What am I doing wrong?

Thanks.

Hi !

You could consider using helper variable for storing result, e.g.

function rot13(str) {
  var result = "";

Then, in the main for loop just append decoded letters with:
result += <result_of_decoding>;

About adjusting the numbers…

  1. Consider the data you are operating on: only uppercase letters - ASCII code from 65 (A) do 90 (Z).
    2, Basically the only thing you should worry about when shifting by 13 is “overflow”: when char code + 13 is bigger than 90. Let’s try to cover that.

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

I’m storing currently processed char code in temporary variable (current) in order to improve readability.

// handle overflow
var decoded;
if (current + 13 > 90) {
var overflow = current + 13 - 90 - 1;
decoded = String.fromCharCode(65 + overflow);
} else {
decoded = String.fromCharCode(current + 13);
}
result += decoded;

If adding 13 to the current makes it bigger than 90, I calculate the difference, then construct string from the calculated char code. The else part handles “normal” situation, without overflow. At the and I append the decoded letter to my result variable.

We almost got it, we only need to pass all the other characters. Let’s wrap everything up:

function rot13(str) { 
  var result = "";
  for (var i = 0; i < str.length; i++) {
    var current = str.charCodeAt(i);
    if (current >= 65 && current <= 90) {
      // handle overflow
      var decoded;
      if (current + 13 > 90) {
        var overflow = current + 13 - 90 - 1;
        decoded = String.fromCharCode(65 + overflow);
      } else {
        decoded = String.fromCharCode(current + 13);
      }
      result += decoded;
    } else {
      result += str[i];
    }
  }
  
  return result;
}

Try to break your code into small, readable peaces - it will make it easier for you and the other to read and understand.
Good luck !

Kind regards,
Jarosław Pawlak

1 Like

Thanks! That was useful.