维吉尼亚密码引入了“密钥”的概念,即根据密钥来决定字符的替换关系。
如上图为维吉尼亚密码的加密过程示意,左边为加密替换表,上面第一行代表明文字母,左面第一列代表密钥字母,对如下明文加密:
TO BE OR NOT TO BE THAT IS THE QUESTION 当选定RELATIONS作为密钥时,加密过程是:明文一个字母为T,第一个密钥字母为R,因此可以找到在R行中代替T的为K,依此类推,得出对应关系如下:
密钥: RE LA TI ONS RE LA TION SR ELA TIONSREL
明文: TO BE OR NOT TO BE THAT IS THE QUESTION
密文: KS ME HZ BBL KS ME MPOG AJ XSE JCSFLZSY 小写字母采用相同的加密表格和加密方法(将上述方法里的大写字母换为小写字母即可)。
遇到数字时,可将其密钥字母在密码表中的偏移量对10取模的结果作为在数字表格中的偏移量,例如:
“1”的密钥“R”在表格中的偏移量为“17”(A在字母表里的偏移量为0),偏移量对10取模结果为“7”,加密时,查表格中“1”对应的列“1 2 3 4 5 6 7 8 9 0”中序号为“7”的数字,得到加密结果应为8,“9”的密钥“E”的偏移量是“4”,在“9”对应的行中序号为“4”的数字是“3”。
密钥: RELA
明文: 1945
密文: 8355
对于不是字母和数字的字符,原样输出。
解密方法与上述操作正好相反,先查出当前字符在密码表中偏移后的位置,再到初始字符集中查找对应的字符。 你的好朋友小明在星期三的早晨给你发了一封电子邮件,你看到的内容是“Km Ztftrs 4, 5723, sgd Tmesdc Rszsdo cqnoodc sdd bncd mzlac "khsskd akx" ne sgd zsklhb anlahjf ne Ghqnrdhlz, Izozm.”。 然后在你在QQ 收到小明发给你的这样一条消息:维吉尼亚问你今天是星期几? 聪明的你猜出来邮件内容是用维吉尼亚加密方法加密过的,密钥是星期三(收到消息的日期)的英文单词,写个程序解密小明的邮件并输出明文吧!
编写一个程序,根据输入的密钥对输入的明文进行加密输出。
格式
输入
输入为两行,第一行是密钥secret_key,第二行是明文plain_text。
输出
输出为一行,是对输入里的明文加密后的密文cipher_text。
样例
输入1
winter
The harsh winter will be gone and spring is around the corner
输出1
Ppr aeiop jbrkaz jbpc xm thrv wvq ltievt bw rnwhgh kdm phveaz
Limitation
1s, 1024KiB for each test case.
代码
借鉴维吉尼亚密码加解密_维吉尼亚密码加密_WhenYa的博客-CSDN博客
import itertools
import string
def encrypt(sentence, k):
words, m = [], Builder(k)
for t in sentence:
if t.isupper():
cnt = (myUpper[t] + next(m)) % 26
words.append(Upper[cnt])
elif t.islower():
cnt = (myLower[t] + next(m)) % 26
words.append(Lower[cnt])
else:
words.append(t)
return listTostr(words)
def Builder(sentence):
mlist = []
for letter in sentence:
mlist.append(myUpper[letter])
return itertools.cycle(mlist)
def listTostr(words):
p = ''
for j in words:
p = p + j
return p
myUpper, myLower, Upper, Lower = {}, {}, {}, {}
cnt1, cnt2 = 0, 0
for i in string.ascii_uppercase:
myUpper[i] = cnt1
Upper[cnt1] = i
cnt1 += 1
for i in string.ascii_lowercase:
myLower[i] = cnt2
Lower[cnt2] = i
cnt2 += 1
key = input()
before = input()
print(encrypt(before, key))