维吉尼亚加密算法

757 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目描述

维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表加密算法,属于多表密码的一种简单形式。

在一个凯撒密码中,字母表中的每一字母都会作一定的偏移,例如偏移量为3时,A就转换为了D、B转换为了E……而维吉尼亚密码则是由一些偏移量不同的恺撒密码组成。

image.png

为了生成密码,需要使用表格法。这一表格(如上图所示)包括了26行字母表,每一行都由前一行向左偏移一位得到。具体使用哪一行字母表进行编译是基于密钥进行的,在过程中会不断地变换。

示例

明文:ATTACKATDAWN
密钥:LEMONLEMONLE
密文:LXFOPVEFRNHR

二、思路分析

例如,假设明文为:

ATTACKATDAWN

选择某一关键词并重复而得到密钥,如关键词为LEMON时,密钥为:

LEMONLEMONLE

对于明文的第一个字母A,对应密钥的第一个字母L,于是使用表格中L行字母表进行加密,得到密文第一个字母L。类似地,明文第二个字母为T,在表格中使用对应的E行进行加密,得到密文第二个字母X。以此类推,可以得到:

明文:ATTACKATDAWN密钥:LEMONLEMONLE密文:LXFOPVEFRNHR

解密的过程则与加密相反。例如:根据密钥第一个字母L所对应的L行字母表,发现密文第一个字母L位于A列,因而明文第一个字母为A。密钥第二个字母E对应E行字母表,而密文第二个字母X位于此行T列,因而明文第二个字母为T。以此类推便可得到明文。

用数字0-25代替字母A-Z,维吉尼亚密码的加密方法可以写成同余的形式:

image.png

解密方法则能写成:

image.png

三、代码

python

str = input("请输入明文:")#ATTACKATDAWN
print("明文转化为数字:")#第一步,将明文转化为数字
array = []
array1 = []
array2 = []
for i in str:
    array.append(ord(i)-65)#ord()方法可以将字符转化为ascall数字
print(array)
str2 = input("请输入密钥:")#LEMONLEMONLE
print("密钥转化为数字:")#第二步,将密钥转化为数字
for i in str2:
    array1.append(ord(i)-65)
print(array1)
for i in range(len(array)):
    array2.append(chr((array[i]+array1[i%len(str2)])%26+65))#chr()方法可以将ascall数字转换为字符
print("密文为:",array2)#LXFOPVEFRNHR

JavaScript

/**
 * @description 维吉尼亚加密算法
 * @param {string} str 明文
 * @param {string} key 秘钥
 * @return {Boolean}
 */
const encrypt = function (str, key) {
  const strArr = [];
  const keyArr = [];
  const res = [];
  for (let i = 0; i < str.length; i++) {
    strArr.push(str[i].charCodeAt() - 65);
  }
  for (let i = 0; i < key.length; i++) {
    keyArr.push(key[i].charCodeAt() - 65);
  }
  for (let i = 0; i < strArr.length; i++) {
    res.push(
      String.fromCharCode(((strArr[i] + keyArr[i % key.length]) % 26) + 65)
    );
  }
  return res.join("");
};
console.log(encrypt("ATTACKATDAWN", "LEMONLEMONLE"));

4、总结

  • 维吉尼亚算法加解密公式 用数字0-25代替字母A-Z,维吉尼亚密码的加密方法可以写成同余的形式:

image.png

解密方法则能写成:

image.png

  • 将字符转化为ascall数字 python 可以使用 ord() 方法,如ord('a'); JavaScript 可以使用 charCodeAt() 方法,如'a'.charCodeAt()。
  • 将ascall数字转换为字符 python 可以使用 chr() 方法,如ch(65); JavaScript 可以使用 String.fromCharCode() 方法,如String.fromCharCode(65)。