被误认为是19世纪密码学家布莱斯-德-维吉纳尔(其他人更早地独立发明了它)的维吉纳尔密码,数百年来都无法破解。它本质上是凯撒密码,只是它使用了一个多部分密钥。所谓的Vigenère钥匙是一个词,甚至是一系列随机的字母。每个字母代表一个数字,通过这个数字来转移信息中的字母。A代表将信息中的一个字母移动到0,B代表1,C代表2,以此类推。
例如,如果一个Vigenère键是 "CAT "这个词,C代表2的移动,A代表0,T代表19。信息的第一个字母被移位2,第二个字母移位0,第三个字母移位19。对于第四个字母,我们重复2的密钥。
这种对多个凯撒密码钥匙的使用,正是维根纳尔密码的优势所在。可能的组合数量太大,无法用蛮力解决。同时,Vigenère密码不存在频率分析的弱点,而频率分析可以破解简单的替换密码。几个世纪以来,维根纳尔密码代表了密码学的最高水平。
你会注意到维根纳尔和凯撒密码程序的代码之间有许多相似之处。关于维根纳尔密码的更多信息可以在https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
如果你想了解更多关于密码和破译的信息,你可以阅读我的《用Python破解密码》No Starch Press, 2018; https://nostarch.com/crackingcodes/
它是如何工作的?
由于加密和解密过程相当相似,
translateMessage()函数处理这两个过程。
encryptMessage()和decryptMessage()函数只是translateMessage()的封装函数。
try:
import pyperclip # pyperclip copies text to the clipboard
except ImportError:
pass # If pyperclip is not installed, do nothing It's no big deal
# Every possible symbol that can be encrypted/decrypted:
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def main():
print('''Vigenère Cipher, by Al Sweigart al@inventwithpythoncom
The Viegenère cipher is a polyalphabetic substitution cipher that was
powerful enough to remain unbroken for centuries''')
# Let the user specify if they are encrypting or decrypting:
while True: # Keep asking until the user enters e or d
print('Do you want to (e)ncrypt or (d)ecrypt?')
response = input('> ').lower()
if response.startswith('e'):
myMode = 'encrypt'
break
elif response.startswith('d'):
myMode = 'decrypt'
break
print('Please enter the letter e or d')
# Let the user specify the key to use:
while True: # Keep asking until the user enters a valid key
print('Please specify the key to use')
print('It can be a word or any combination of letters:')
response = input('> ').upper()
if response.isalpha():
myKey = response
break
# Let the user specify the message to encrypt/decrypt:
print('Enter the message to {}'.format(myMode))
myMessage = input('> ')
# Perform the encryption/decryption:
if myMode == 'encrypt':
translated = encryptMessage(myMessage, myKey)
elif myMode == 'decrypt':
translated = decryptMessage(myMessage, myKey)
print('%sed message:' % (myMode.title()))
print(translated)
try:
pyperclip.copy(translated)
print('Full %sed text copied to clipboard' % (myMode))
except:
pass # Do nothing if pyperclip wasn't installed
def encryptMessage(message, key):
"""Encrypt the message using the key"""
return translateMessage(message, key, 'encrypt')
def decryptMessage(message, key):
"""Decrypt the message using the key"""
return translateMessage(message, key, 'decrypt')
def translateMessage(message, key, mode):
"""Encrypt or decrypt the message using the key"""
translated = [] # Stores the encrypted/decrypted message string
keyIndex = 0
key = key.upper()
for symbol in message: # Loop through each character in message
num = LETTERS.find(symbol.upper())
if num != -1: # - means symbolupper() was not in LETTERS
if mode == 'encrypt':
# Add if encrypting:
num += LETTERS.find(key[keyIndex])
elif mode == 'decrypt':
# Subtract if decrypting:
num -= LETTERS.find(key[keyIndex])
num %= len(LETTERS) # Handle the potential wrap-around
# Add the encrypted/decrypted symbol to translated
if symbol.isupper():
translated.append(LETTERS[num])
elif symbol.islower():
translated.append(LETTERS[num].lower())
keyIndex += 1 # Move to the next letter in the key
if keyIndex == len(key):
keyIndex = 0
else:
# Just add the symbol without encrypting/decrypting:
translated.append(symbol)
return ''.join(translated)
# If this program was run (instead of imported), run the program:
if __name__ == '__main__':
main()
换句话说,它们是调整其参数的函数,将这些参数转发给另一个函数,然后返回该函数的返回值。这个程序使用了这些包装函数,这样就可以以类似于项目66 "简单替代密码 "中的encryptMessage()和decryptMessage()的方式来调用它们。你可以将这些项目作为模块导入其他程序中,以利用其加密代码,而不必将代码直接复制和粘贴到新程序中。
网友评论