【问题标题】:Encrypting a string using a key and vigenere cipher already generated by another function使用已由另一个函数生成的密钥和 vigenere 密码加密字符串
【发布时间】:2020-01-05 19:06:29
【问题描述】:

我一直无法弄清楚如何在我的程序中编写和实现几个函数。调用 get_col_index 和 get_row_index 方法的 encrypt 方法,以及 get_col_index 和 get_row_index 方法。 encrypt方法由main方法调用,传递message、key、vignere_square。 Vignere 矩阵密码已经在一个单独的函数中生成。 encrypt 方法然后调用 get_col_index 和 get_row_index 方法来加密消息,跳过所有不是字母的内容。

我的大部分问题是弄清楚如何使用 get_row_index 和 get_col_index 方法对消息进行编码。对于get_col_index,我们通过消息和vigenere square,它返回消息中每个字母的列索引。对于get_row_index,我们通过key和vigenere square,它返回key的每个字母的行索引。我一直在尝试为这些函数使用for循环,我通常会返回消息(未加密),带有随机字母或错误的列表。这是我最近的尝试,我尝试在加密方法中使用附加,但它只是将消息和密钥添加到列表中。

def main():
    vig_square = create_vig_square()
    message = input("Enter a multi-word message with punctuation: ")
    input_key = input("Enter a single word key with no punctuation: ")
    msg = message.lower()
    key = input_key.lower()
    print("The encoded message is: ",encrypt(msg, key, vig_square))
    print("The decoded message is: ")

def encrypt(msg, key, vig_square):
    msg_char = msg
    key_char = key
    coded_msg = list()
    coded_msg.append(get_col_index(msg_char, vig_square))
    coded_msg.append(get_row_index(key_char, vig_square))
    return coded_msg

def get_col_index(msg_char, vig_square):
    column_index = ""
    for i in range(len(vig_square)):
        column_index = msg_char
        i += 1
    return column_index

def get_row_index(key_char, vig_square):
    row_index =  ""
    for i in range(len(vig_square)):
        row_index = key_char
        i += 1
    return row_index


def create_vig_square():
    vig_square = list()
    for row in range(26):
        next_row = list()
        chr_code = ord('a') + row
        for col in range(26):
            letter = chr(chr_code)
            next_row.append(letter)
            chr_code = chr_code + 1
            if chr_code > 122:
                chr_code = ord('a')
        vig_square.append(next_row)
    return vig_square

main()

我希望输出是这样的:

The eagle has landed.

Enter a single word key with no punctuation:
LINKED

The encoded message is:
epr oejwm ukw olvqoh.

The decoded message is:
the eagle has landed.

【问题讨论】:

    标签: python list encryption vigenere


    【解决方案1】:

    vignere 密码有一些很好的属性,因为 vignere 正方形在水平和垂直方向都是循环的,这意味着可以这样进行查找:

    # assume col and row are lowercase letters
    def vignere_lookup(col, row):
      base = ord('a')
      index = ((ord(col) - base) + (ord(row) - base)) % 26
      return chr(base + index)
    

    这会将字母 a-z 分配给数字 0-25,添加列和行字母,并在值高于 'z'(25) 的情况下使用模数来遍历

    这意味着可以通过以下方式进行加密:

    def encrypt(message, key):
      ciphertext = ''
      key_index = 0
      # convert to lower case
      for letter in message.lower():
        # only encrypt the letters a-z, for space, punctuation, numbers, just add the raw letter
        if ord(letter) in range(ord('a'), ord('z') + 1):
          # make sure to lowercase the key as well
          ciphertext += vignere_lookup(letter, key[key_index % len(key)].lower())
          key_index += 1
        else:
          ciphertext += letter
    
      return ciphertext
    

    同样,解密查找可以使用减法来完成,利用在 python 中,我们希望对负数循环使用取模这一事实。这给出了解密为:

    def vignere_reverse(col, target):
      base = ord('a')
      # notice the subtraction instead of addition
      index = ((ord(col) - base) - (ord(target) - base)) % 26
      return chr(base + index)
    
    def decrypt(cipher, key):
      message = ''
      key_index = 0
      for letter in cipher.lower():
        if ord(letter) in range(ord('a'), ord('z') + 1):
          message += vignere_reverse(letter, key[key_index % len(key)].lower())
          key_index += 1
        else:
          message += letter
    
      return message
    

    把所有这些放在一起,你就可以做到:

    cipher = encrypt("The eagle has landed.", "LINKED")
    print(cipher) # prints "epr oejwm ukw olvqoh."
    decrypted = decrypt(cipher, "LINKED")
    print(decrypted) # prints "the eagle has landed."
    

    【讨论】:

    • 感谢您的回复。我如何将此方法实现为两个单独的函数(get_row_index 和 get_col_index)? col 函数从消息中获取列号,row 函数从 key 中获取行索引,然后在 encrypt 函数中将它们组合以创建密码。我已尝试将您的代码的 sn-ps 并将它们实现到我的函数中,但结果并不正确。
    • 这取决于您对索引的确切含义。如果它是用于查看二维数组的索引,当您存储 vignere 正方形时,(小写)字母的索引就是 ord(letter) - ord('a')。请注意,您实际上不必生成正方形来加密和解密。
    猜你喜欢
    • 1970-01-01
    • 2010-12-02
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 2017-10-08
    • 1970-01-01
    • 2012-10-05
    相关资源
    最近更新 更多