Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
一、题目描述
维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式。
在一个凯撒密码中,字母表中的每一字母都会作一定的偏移,例如偏移量为3时,A就转换为了D、B转换为了E……而维吉尼亚密码则是由一些偏移量不同的恺撒密码组成。
为了生成密码,需要使用表格法。这一表格(如上图所示)包括了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,维吉尼亚密码的加密方法可以写成同余的形式:
解密方法则能写成:
三、代码
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,维吉尼亚密码的加密方法可以写成同余的形式:
解密方法则能写成:
- 将字符转化为ascall数字 python 可以使用 ord() 方法,如ord('a'); JavaScript 可以使用 charCodeAt() 方法,如'a'.charCodeAt()。
- 将ascall数字转换为字符 python 可以使用 chr() 方法,如ch(65); JavaScript 可以使用 String.fromCharCode() 方法,如String.fromCharCode(65)。