0

Trying to get a JS function to work that shifts the individual characters in a string by a set amount (and then returns the new "shifted" string). I'm using ROT-13 (so A-M are shifted down 13 characters and N-Z are shifted up 13 characters).

The trouble lies with this piece of code:

if (arr[i] <= 77) {
    finalStr += String.fromCharCode(arr[i] + 13);

This code should shift E to R.

E (69) + 13 = R (82)

However, the characters in the returned string that should be shifted down 13 spaces return as weird symbols.

"FᬁEE಍C᧕DE಍CAMᨹ"

function rot13(str) {
  var newStr = "";
  var finalStr = "";
  for (i = 0, j = str.length; i < j; i++) {
    newStr += str.charCodeAt(i);
    newStr += " ";
  }
  var arr = newStr.split(" ");
  arr.pop();
  for (i = 0, j = arr.length; i < j; i++) {
    if (arr[i] !== 32) {
      if (arr[i] <= 77) {
        finalStr += String.fromCharCode(arr[i] + 13);
      }
      else {
        finalStr += String.fromCharCode(arr[i] - 13);
      }
    }
  }
  return finalStr;
}

rot13("SERR PBQR PNZC");
GoMagikarp
  • 85
  • 1
  • 7

3 Answers3

0

The problem doesn't appear to be what you identified but rather your handling of the conversion from characters to character codes. Simplifying and cleaning up your conversioin logic seems to fix the problem:

function rot13(str) {

    var arr = new Array();

    for (var i = 0; i < str.length; i++) {
        arr[arr.length] = str.charCodeAt(i);
    }

    var finalStr = "";

    for (var i = 0; i < arr.length; i++) {
        if (arr[i] !== 32) {
            if (arr[i] <= 77) {
                finalStr += String.fromCharCode(arr[i] + 13);
            } else {
                finalStr += String.fromCharCode(arr[i] - 13);
            }
        } else {
            finalStr += String.fromCharCode(32);
        }
    }

    return finalStr;
}

rot13("SERR PBQR PNZC");

Which returns "FREE CODE CAMP".

cdlane
  • 40,441
  • 5
  • 32
  • 81
0

And just to blow your mind a little more:

var rot13=function(str){
  return str.split('')
    .map(function(ch){
      var v=ch.charCodeAt(0); 
      return String.fromCharCode(v > 77 ? v-13 : v+13);
    })
    .join('');
};

UPDATE - Version that handles both upper and lower-cased letters

var rot13 = function(s){
    return s.split('').map(function(c){
      var v=c.toLowerCase().charCodeAt(0);
      if(v<97 || v>122) return c;
      var t = v>=96,
          k = (v - 96 + 12) % 26 + 1;
      return String.fromCharCode(k + (t ? 96 : 64));
  }).join('');
};

rot13('SERR PBQR PNZC') // => FREE CODE CAMP
Rob Raisch
  • 17,040
  • 4
  • 48
  • 58
  • I tried to answer the question in terms of the OP's own code, but if you're going to go this route, then: `function rot13(s) { return s.replace(/[A-Z]/g, function (c) { return String.fromCharCode(((c.charCodeAt(0) - 52) % 26) + 65); } ); }` – cdlane Mar 22 '16 at 01:10
  • @cdlane: Like most good programming languages, _there is always more than one way to accomplish your goal_. (Apologies to Larry Wall.) My solution is more general as yours assumes the string to be en/decoded will always only contain capital letters. But it's a good one nonetheless. – Rob Raisch Mar 22 '16 at 18:03
  • Excuse me, did you try lower casing the input and running it through your solution? fXee-cUde-camV to you too! – cdlane Mar 22 '16 at 18:13
  • Ouch, just discovered that. Mea Culpa. ;) – Rob Raisch Mar 22 '16 at 18:42
0

Just had an idea : why not doing it on one line only ? And by the way, I looked at the Free Code Camp challenge and u have to bypass all non alphanumerical characters. Here it is :

function rot13(str) { // LBH QVQ VG!
  return str.split('').map(function(letter){
    return letter.match(new RegExp(/\W/i)) ? letter : (letter.charCodeAt(0) <= 77 ? String.fromCharCode(letter.charCodeAt(0) + 13) : String.fromCharCode(letter.charCodeAt(0) - 13));
  }).join('');
}

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

TADAAAAH :-)

Here is the pen : http://codepen.io/liorchamla/pen/mPwdEz/

Hope u will like it and also hope you will try hard to understand this !

Happy Free Code Camp to all !

Lior CHAMLA
  • 128
  • 8