1

I made the Vigenère cipher in JavaScript.

if I run my Code in Firefox I'm getting the follow output:

�QZ4Sm0]m

in Google Chrome it looks like this

QZ4Sm0]m

How can I avoid those symbols or how can I make them visible? What am I doing wrong?

function vigenere(key, str, mode) {
  var output = [str.length];
  var result = 0;
  var output_str;

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

    if (mode == 1) {
      result = ((str.charCodeAt(i) + key.charCodeAt(i % key.length)) % 128);
      output[i] = String.fromCharCode(result);
    } else if (mode == 0) {
      if (str.charCodeAt(i) - key.charCodeAt(i % key.length) < 0) {
        result = (str.charCodeAt(i) - key.charCodeAt(i % key.length)) + 128;
      } else {
        result = (str.charCodeAt(i) - key.charCodeAt(i % key.length)) % 128;
      }
      output[i] = String.fromCharCode(result);
    }

  }
  output_str = output.join('');
  return output_str;
}

console.log(vigenere("Key", "Plaintext", 1))
mplungjan
  • 169,008
  • 28
  • 173
  • 236
saltea
  • 37
  • 6

3 Answers3

1

Your first calculation gives an esc (#27) in all browsers. Visible in Firefox, but not visible in Chrome

This one gives Zpysrrobr: https://www.nayuki.io/page/vigenere-cipher-javascript

function vigenere(key, str, mode) {
  var output = [str.length];
  var result = 0;
  var output_str;

  for (var i = 0; i < str.length; i++) {
    if (mode == 1) {
      result = ((str.charCodeAt(i) + key.charCodeAt(i % key.length)) % 128);
      output[i] = String.fromCharCode(result);
      console.log( 
      str[i],key[i],result,output[i])

    } else if (mode == 0) {
      if (str.charCodeAt(i) - key.charCodeAt(i % key.length) < 0) {
        result = (str.charCodeAt(i) - key.charCodeAt(i % key.length)) + 128;
      } else {
        result = (str.charCodeAt(i) - key.charCodeAt(i % key.length)) % 128;
      }
      output[i] = String.fromCharCode(result);
    }

  }
  output_str = output.join('');
  return output_str;
}

console.log(vigenere("Key", "Plaintext", 1))
mplungjan
  • 169,008
  • 28
  • 173
  • 236
0

Try using this piece of code. Its simpler and quite readable

function vigenereFunc(plainText, key) {
   const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   let cipherText = "";
   for (let i = 0, j = 0; i < plainText.length; i++) {
     if (!letters.includes(plainText[i])) {
       cipherText += plainText[i];
          continue;
     }
     cipherText += letters[(letters.indexOf(plainText[i]) + letters.indexOf(key[j])) % 26];

     if(j === key.length - 1) j = -1;
     return cipherText;
  }
0

Here: This implements the Vigenere cipher correctly. It preserves capitilization, encryption and decryption is kept in the same function, and it's easily readable. Your code was likely making the � symbol because it's attempting to use unicode values greater than 127, which can make some invalid characters in the output.

function vigenere(message, keyword, operation) {
  // Example usage: let encryptedMessage = vigenere("hello", "supersecret", "enc");
  const alphabet = "abcdefghijklmnopqrstuvwxyz";

  let result = "";
  let keywordIndex = 0;

  // Determine whether to encrypt or decrypt
  let shift;
  if (operation === "enc") {
    shift = 1;
  } else if (operation === "dec") {
    shift = -1;
  } else {
    console.error(
      "Invalid operation! Must be enc or dec, for encrypt or decrypt."
    );
    return;
  }

  for (let i = 0; i < message.length; i++) {
    const char = message[i];
    const charIndex = alphabet.indexOf(char.toLowerCase());

    // Check if character is a letter
    if (charIndex >= 0) {
      const keywordChar = keyword[keywordIndex % keyword.length];
      const keywordIndexInAlphabet = alphabet.indexOf(
        keywordChar.toLowerCase()
      );
      const isUpperCase = char === char.toUpperCase();
      const shiftedCharIndex =
        (charIndex + shift * keywordIndexInAlphabet + 26) % 26;
      let shiftedChar = alphabet[shiftedCharIndex];

      if (isUpperCase) {
        shiftedChar = shiftedChar.toUpperCase();
      }

      result += shiftedChar;

      // Increment keyword index
      keywordIndex++;
    } else {
      result += char;
    }
  }

  return result;
}
let msg = prompt('Message to encrypt or decrypt')
let key = prompt('Keyword to encrypt or decrypt the message')
let op = prompt('Operation (type enc for encrypt or dec for decrypt)')
let output = 'Encrypted message: ' + vigenere(msg, key, op)
console.log(output)
alert(output)
  • 1
    Please avoid code only answer, and add some explanation. Especially when answering to old questions, it is important to explain why your answer is different, and even better than existing answers. – chrslg Jun 05 '23 at 15:49