vigenere Cipher Algorithm

The Vigenère Cipher Algorithm is a classic method of encrypting alphabetic text that uses a simple form of polyalphabetic substitution. Developed in the mid-16th century by French cryptographer Blaise de Vigenère, the algorithm relies on a repeated shift of characters based on a secret key. It is considered an improvement over the Caesar cipher, which only uses a single fixed shift, making the Vigenère cipher more secure and harder to break as it uses multiple shifts, thus increasing the complexity of the encryption. The Vigenère Cipher Algorithm works by using a table of alphabets called the Vigenère square, which consists of 26 rows of shifted alphabets. The plaintext message is first combined with a secret key, which is repeated or truncated to match the length of the plaintext. The encryption is performed by looking up the plaintext letter in the first column of the table and the corresponding key letter in the top row, then finding the intersection of these two letters in the table, which forms the ciphertext. Decryption is done by reversing the process: finding the ciphertext letter in the top row, then going down the column to find the key letter, and finally, locating the plaintext letter in the first column. The Vigenère cipher provides a basic level of security, but it can be broken with modern cryptanalysis techniques, such as frequency analysis and the Kasiski examination.
/**
 * Check if the Character is letter or not
 * @param {String} str - character to check
 * @return {object} An array with the character or null if isn't a letter
 */
function isLetter (str) {
  return str.length === 1 && str.match(/[a-zA-Z]/i)
}

/**
 * Check if is Uppercase or Lowercase
 * @param {String} character - character to check
 * @return {Boolean} result of the checking
 */
function isUpperCase (character) {
  if (character === character.toUpperCase()) {
    return true
  }
  if (character === character.toLowerCase()) {
    return false
  }
}

/**
 * Encrypt a Vigenere cipher
 * @param {String} message - string to be encrypted
 * @param {String} key - key for encrypt
 * @return {String} result - encrypted string
 */
function encrypt (message, key) {
  let result = ''

  for (let i = 0, j = 0; i < message.length; i++) {
    const c = message.charAt(i)
    if (isLetter(c)) {
      if (isUpperCase(c)) {
        result += String.fromCharCode((c.charCodeAt(0) + key.toUpperCase().charCodeAt(j) - 2 * 65) % 26 + 65) // A: 65
      } else {
        result += String.fromCharCode((c.charCodeAt(0) + key.toLowerCase().charCodeAt(j) - 2 * 97) % 26 + 97) // a: 97
      }
    } else {
      result += c
    }
    j = ++j % key.length
  }
  return result
}

/**
 * Decrypt a Vigenere cipher
 * @param {String} message - string to be decrypted
 * @param {String} key - key for decrypt
 * @return {String} result - decrypted string
 */
function decrypt (message, key) {
  let result = ''

  for (let i = 0, j = 0; i < message.length; i++) {
    const c = message.charAt(i)
    if (isLetter(c)) {
      if (isUpperCase(c)) {
        result += String.fromCharCode(90 - (25 - (c.charCodeAt(0) - key.toUpperCase().charCodeAt(j))) % 26)
      } else {
        result += String.fromCharCode(122 - (25 - (c.charCodeAt(0) - key.toLowerCase().charCodeAt(j))) % 26)
      }
    } else {
      result += c
    }
    j = ++j % key.length
  }
  return result
}

const messageEncrypt = encrypt('Hello World!', 'code')
console.log(messageEncrypt) // "Jhpnr Yrvng!"

const messageDecrypt = decrypt('Jsopq Zstzg!', 'code')
console.log(messageDecrypt) // "Hello World!"

LANGUAGE:

DARK MODE: