skip to Main Content

Caesar Cipher is just changing each letter shifting it by 13 places.
I know i can do it with indexOf, but i tried to do it with arrays and a for..loop
but I’m having problems with it, can someone tell me what’s wrong?

function rot13(str) {
  let letter = str.split("")
  let cipher = [
    ["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"]
  ]
  for (let i = 0; i < letter.length; i++) {
    for (let j = 0; j < cipher.length; j++) {
      if (letter[i] === cipher[j][0]) {
        letter.splice(letter[i], 1, cipher[j][1])
      } else if (letter[i] === cipher[j][1]) {
        letter.splice(letter[i], 1, cipher[j][0])
      }
    }
  }
  return letter.join("")
}

console.log(rot13("SERR PBQR PNZC"));

2

Answers


  1. You’ve got several issues:

    1. letter.splice(letter[i], 1, cipher[j][1]): In .splice(), the first argument should be the index, not the element. Use i instead of letter[i].
    2. The cipher array doesn’t cover all alphabets (e.g., N-Z to A-M).
    3. You’re not handling non-alphabetic characters.

    Here’s a revised version that should work:

    // Initialize all 26 possible ciphers in memory
    const allCiphers = new Map();
    for (let rotation = 0; rotation < 26; rotation++) {
      const cipher = new Map();
      for (let i = 0; i < 26; i++) {
        const charA = String.fromCharCode(65 + i);
        const charB = String.fromCharCode(65 + (i + rotation) % 26);
        cipher.set(charA, charB);
      }
      allCiphers.set(rotation, cipher);
    }
    
    function rot(str, rotation) {
      const rotationMod = rotation % 26;
      const cipher = allCiphers.get(rotationMod);
      let letter = str.split("");
      for (let i = 0; i < letter.length; i++) {
        if (cipher.has(letter[i])) {
          letter[i] = cipher.get(letter[i]);
        }
      }
      return letter.join("");
    }
    
    function rot13(str) {
      return rot(str, 13);
    }
    
    function updateButtonText() {
      const rotation = document.getElementById("rotation").value;
      document.getElementById("runButton").textContent = `Run ROT${rotation}`;
    }
    
    function runRot() {
      const inputText = document.getElementById("inputText").value.toUpperCase();
      const rotation = parseInt(document.getElementById("rotation").value, 10);
      const result = rot(inputText, rotation);
      document.getElementById("result").textContent = result;
    }
    
    updateButtonText();  // Initialize button text
    * {
      font-family: sans-serif;
    }
    <!DOCTYPE html>
    <html>
    <head>
      <title>Caesar Cipher</title>
    </head>
    <body>
      <input type="text" id="inputText" placeholder="Enter text">
      <input type="number" id="rotation" min="0" value="13" onchange="updateButtonText()">
      <button id="runButton" onclick="runRot()">Run ROT13</button>
      <p><b>Result:</b> <span id="result"></span></p>
    </body>
    </html>
    Login or Signup to reply.
  2. letter element is an Array of 1 character,
    you don’t need to use .slice() method.
    just change
    letter.splice(letter[i], 1, cipher[j][1])
    by
    letter[i] = cipher[j][1];

    PS: I also added some break;

    function rot13(str)
      {
      let letter = str.split('')
        , cipher = [ ['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'] ]
        ;
      for (let i = 0; i < letter.length; i++) 
        {
        for (let j = 0; j < cipher.length; j++) 
          {
          if (letter[i] === cipher[j][0]) { letter[i] = cipher[j][1]; break; }
          if (letter[i] === cipher[j][1]) { letter[i] = cipher[j][0]; break; }
          }
        }
      return letter.join('');
      }
    
    console.log(rot13('SERR PBQR PNZC'));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search