美文网首页
维吉纳尔密码

维吉纳尔密码

作者: 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