原理
维吉尼亚密码,它将凯撒密码的所有26种排列放到一个表中,形成26行26列的加密字母表。此外,维吉尼亚密码必须有一个由字母组成的密钥,至少有一个字母,最多与明文字母有相同数量的字母。
在凯撒密码中,每个字母都会进行一定偏移值转换,例如,当偏移值是3时,则B被转换为E,C转换成F......。在维吉尼亚密码加密中,则是由具有不同偏移的凯撒密码构成的。
要生成密码,需要使用表格方法,此表(如图所示)包含26行字母表,每一行从上一行到左行被一位偏移。加密时使用哪一行字母表是基于密钥的,在加密过程中密钥会不断变化。
例如,假设明文为:
BTTACKATDAFG
选择一个关键字并重复它以获得密钥,例如,当关键字是LIMN时,键是:
LIMNLIMNLIMN
在明文中的第一个字母B,对应于密钥中的第一个字母L,使用加密字母表中的L行字母进行加密,得到第一个字母的密文M。同样,第二个明文字母是T,它用表中的I行加密,得到第二个密文B。通过类比,我们可以得到:
明文:BTTACKATDAFG 键:LIMNLIMNLIMN 密文:MBFNNSMGOIRT
解密的过程是加密的逆过程。例如,密钥的第一个字母对应的L行字母表,发现密文的第一个字母M位于B列,因此明文的第一个字母是B。密钥的第二个字母对应于I行字母表,而密文的第二个字母B位于该行的T列中,因此明文的第二个字母是T。等等,你可以得到明文。转自:http://www.metools.info/code/c71.html
加密与解密
# -*- coding:utf-8 -*- import string letters = string.ascii_letters def encode_s(plaintext, key): encode = '' j = 0 # 非字母字符数量 for i,value in enumerate(plaintext): if value.isalpha(): n = (letters.find(plaintext[i]) + letters.find(key[i-j])) % 26 # 移位后的字母位置(大小写字母处理为相同情况) if value.isupper(): n += 26 # 大写字母要比小写字母高26位 encode += letters[n] else: encode += value j += 1 return encode def decode_s(ciphertext, key): decode = '' j = 0 # 非字母字符数量 for i, value in enumerate(ciphertext): if value.isalpha(): n = (letters.find(ciphertext[i]) - letters.find(key[i - j])) % 26 # 移位后的字母位置(大小写字母处理为相同情况) if value.isupper(): n += 26 # 大写字母要比小写字母高26位 decode += letters[n] else: decode += value j += 1 return decode # 处理秘钥和明文长度相同 def keyprocess(key,plaintext): n = len(key) m = len(plaintext) if n > m: return key[:len(plaintext)],plaintext elif n < m: i = m // n j = m % n return key*i+key[:j],plaintext if __name__ == '__main__': text1 = 'comegreatwall' key = 'crypto' key,text1 = keyprocess(key,text1) print (encode_s(text1,key)) text2 = 'efktzfgrrltzn' print (decode_s(text2,key))