Skip to content

Instantly share code, notes, and snippets.

@Folasayo-Samuel
Forked from martin-mok/CaesarsCipher.md
Created February 21, 2022 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Folasayo-Samuel/b5eda7207519ac5a8bfa9cace4ebd89c to your computer and use it in GitHub Desktop.
Save Folasayo-Samuel/b5eda7207519ac5a8bfa9cace4ebd89c to your computer and use it in GitHub Desktop.
freecodecamp: Caesars Cipher

Description

One of the simplest and most widely known ciphers is a Caesar cipher, also known as a shift cipher. In a shift cipher the meanings of the letters are shifted by some set amount. A common modern use is the ROT13 cipher, where the values of the letters are shifted by 13 places. Thus 'A' ↔ 'N', 'B' ↔ 'O' and so on. Write a function which takes a ROT13 encoded string as input and returns a decoded string. All letters will be uppercase. Do not transform any non-alphabetic character (i.e. spaces, punctuation), but do pass them on.

Tests

tests:
  - text: <code>rot13("SERR PBQR PNZC")</code> should decode to <code>FREE CODE CAMP</code>
    testString: assert(rot13("SERR PBQR PNZC") === "FREE CODE CAMP");
  - text: <code>rot13("SERR CVMMN!")</code> should decode to <code>FREE PIZZA!</code>
    testString: assert(rot13("SERR CVMMN!") === "FREE PIZZA!");
  - text: <code>rot13("SERR YBIR?")</code> should decode to <code>FREE LOVE?</code>
    testString: assert(rot13("SERR YBIR?") === "FREE LOVE?");
  - text: <code>rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.")</code> should decode to <code>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.</code>
    testString: assert(rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.") === "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.");

Solution

Offical soln:

var lookup = {
  'A': 'N','B': 'O','C': 'P','D': 'Q',
  'E': 'R','F': 'S','G': 'T','H': 'U',
  'I': 'V','J': 'W','K': 'X','L': 'Y',
  'M': 'Z','N': 'A','O': 'B','P': 'C',
  'Q': 'D','R': 'E','S': 'F','T': 'G',
  'U': 'H','V': 'I','W': 'J','X': 'K',
  'Y': 'L','Z': 'M'
};

function rot13(encodedStr) {
  var codeArr = encodedStr.split("");  // String to Array
  var decodedArr = []; // Your Result goes here
  // Only change code below this line

  decodedArr = codeArr.map(function(letter) {
    if(lookup.hasOwnProperty(letter)) {
      letter = lookup[letter];
    }
    return letter;
  });

  // Only change code above this line
  return decodedArr.join(""); // Array to String
}

My soln:

function rot13(str) { // LBH QVQ VG!
  const Acode='A'.charCodeAt();
  const Ncode='N'.charCodeAt();
  const Zcode='Z'.charCodeAt();
  return [...str].map(
    function(e){
      const code=e.charCodeAt();
      if(Acode<=code && code<=Zcode){
        if(code<Ncode){
          return String.fromCharCode(code+13);
        } else {
          return String.fromCharCode(code-13);
        }
      } else {
        return e;
      }
    }
  ).join("");
}

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

freeCodeCamp Challenge Guide: Caesars Cipher:
Soln 2:

// Solution with Regular expression and Array of ASCII character codes
function rot13(str) {
  var rotCharArray = [];
  var regEx = /[A-Z]/;
  str = str.split("");
  for (var x in str) {
    if (regEx.test(str[x])) {
      // A more general approach
      // possible because of modular arithmetic
      // and cyclic nature of rot13 transform
      rotCharArray.push(((str[x].charCodeAt() - 65 + 13) % 26) + 65);
    } else {
      rotCharArray.push(str[x].charCodeAt());
    }
  }
  str = String.fromCharCode.apply(String, rotCharArray);
  return str;
}
Algorithm Explanation:

    ALPHA	KEY	BASE 	 	 	 ROTATED	ROT13
    -------------------------------------------------------------
    [A]     65  <=>   0 + 13  =>  13 % 26  <=>  13 + 65 = 78 [N]
    [B]     66  <=>   1 + 13  =>  14 % 26  <=>  14 + 65 = 79 [O]
    [C]     67  <=>   2 + 13  =>  15 % 26  <=>  15 + 65 = 80 [P]
    [D]     68  <=>   3 + 13  =>  16 % 26  <=>  16 + 65 = 81 [Q]
    [E]     69  <=>   4 + 13  =>  17 % 26  <=>  17 + 65 = 82 [R]
    [F]     70  <=>   5 + 13  =>  18 % 26  <=>  18 + 65 = 83 [S]
    [G]     71  <=>   6 + 13  =>  19 % 26  <=>  19 + 65 = 84 [T]
    [H]     72  <=>   7 + 13  =>  20 % 26  <=>  20 + 65 = 85 [U]
    [I]     73  <=>   8 + 13  =>  21 % 26  <=>  21 + 65 = 86 [V]
    [J]     74  <=>   9 + 13  =>  22 % 26  <=>  22 + 65 = 87 [W]
    [K]     75  <=>  10 + 13  =>  23 % 26  <=>  23 + 65 = 88 [X]
    [L]     76  <=>  11 + 13  =>  24 % 26  <=>  24 + 65 = 89 [Y]
    [M]     77  <=>  12 + 13  =>  25 % 26  <=>  25 + 65 = 90 [Z]
    [N]     78  <=>  13 + 13  =>  26 % 26  <=>   0 + 65 = 65 [A]
    [O]     79  <=>  14 + 13  =>  27 % 26  <=>   1 + 65 = 66 [B]
    [P]     80  <=>  15 + 13  =>  28 % 26  <=>   2 + 65 = 67 [C]
    [Q]     81  <=>  16 + 13  =>  29 % 26  <=>   3 + 65 = 68 [D]
    [R]     82  <=>  17 + 13  =>  30 % 26  <=>   4 + 65 = 69 [E]
    [S]     83  <=>  18 + 13  =>  31 % 26  <=>   5 + 65 = 70 [F]
    [T]     84  <=>  19 + 13  =>  32 % 26  <=>   6 + 65 = 71 [G]
    [U]     85  <=>  20 + 13  =>  33 % 26  <=>   7 + 65 = 72 [H]
    [V]     86  <=>  21 + 13  =>  34 % 26  <=>   8 + 65 = 73 [I]
    [W]     87  <=>  22 + 13  =>  35 % 26  <=>   9 + 65 = 74 [J]
    [X]     88  <=>  23 + 13  =>  36 % 26  <=>  10 + 65 = 75 [K]
    [Y]     89  <=>  24 + 13  =>  37 % 26  <=>  11 + 65 = 76 [L]
    [Z]     90  <=>  25 + 13  =>  38 % 26  <=>  12 + 65 = 77 [M]

Soln 3:

function rot13(str) {
  // LBH QVQ VG!
  return str.replace(/[A-Z]/g, L =>
    String.fromCharCode((L.charCodeAt(0) % 26) + 65)
  );
}
As you can notice, each number in the range of [65 - 90] maps to a unique number between [0 - 25].
You might have also noticed that each given number (e.g. 65) maps to another number (e.g. 13) which can be used as an offset value
(i.e. 65 + OFFSET) to get the ROT13 of the given number.

E.g. 65 maps to 13 which can be taken as an offset value and added to 65 to give 78.

    [A]  65 % 26 ⇔ 13 + 65 =  78 [N]
    [B]  66 % 26 ⇔ 14 + 65 =  79 [O]
    [C]  67 % 26 ⇔ 15 + 65 =  80 [P]
    [D]  68 % 26 ⇔ 16 + 65 =  81 [Q]
    [E]  69 % 26 ⇔ 17 + 65 =  82 [R]
    [F]  70 % 26 ⇔ 18 + 65 =  83 [S]
    [G]  71 % 26 ⇔ 19 + 65 =  84 [T]
    [H]  72 % 26 ⇔ 20 + 65 =  85 [U]
    [I]  73 % 26 ⇔ 21 + 65 =  86 [V]
    [J]  74 % 26 ⇔ 22 + 65 =  87 [W]
    [K]  75 % 26 ⇔ 23 + 65 =  88 [X]
    [L]  76 % 26 ⇔ 24 + 65 =  89 [Y]
    [M]  77 % 26 ⇔ 25 + 65 =  90 [Z]
    [N]  78 % 26 ⇔  0 + 65 =  65 [A]
    [O]  79 % 26 ⇔  1 + 65 =  66 [B]
    [P]  80 % 26 ⇔  2 + 65 =  67 [C]
    [Q]  81 % 26 ⇔  3 + 65 =  68 [D]
    [R]  82 % 26 ⇔  4 + 65 =  69 [E]
    [S]  83 % 26 ⇔  5 + 65 =  70 [F]
    [T]  84 % 26 ⇔  6 + 65 =  71 [G]
    [U]  85 % 26 ⇔  7 + 65 =  72 [H]
    [V]  86 % 26 ⇔  8 + 65 =  73 [I]
    [W]  87 % 26 ⇔  9 + 65 =  74 [J]
    [X]  88 % 26 ⇔ 10 + 65 =  75 [K]
    [Y]  89 % 26 ⇔ 11 + 65 =  76 [L]
    [Z]  90 % 26 ⇔ 12 + 65 =  77 [M]

Soln 4:

function rot13(str) {
    const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    return str
      .split('')
      .map(char => {  
        const pos = alphabet.indexOf(char);      
        return pos >= 0 ? alphabet[(pos + 13) % 26] : char;
      })
      .join('');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment