美文网首页
维吉纳尔密码

维吉纳尔密码

作者: Python_Camp | 来源:发表于2022-06-28 18:16 被阅读0次

被误认为是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()的方式来调用它们。你可以将这些项目作为模块导入其他程序中,以利用其加密代码,而不必将代码直接复制和粘贴到新程序中。

相关文章

网友评论

      本文标题:维吉纳尔密码

      本文链接:https://www.haomeiwen.com/subject/sqinvrtx.html