如何让我的 Vigenère Cipher 忽略原始消息中的空格

Posted

技术标签:

【中文标题】如何让我的 Vigenère Cipher 忽略原始消息中的空格【英文标题】:How can I make my Vigenère Cipher ignore spaces in the original message 【发布时间】:2016-01-14 21:47:42 【问题描述】:

我正在尝试制作 Vigenère Cipher,但我似乎无法找到一种方法来实现在输入消息然后打印最终结果时忽略输入空格的功能,例如:我输入起始消息:“ python 计算”然后我输入密钥:“堆栈”如果程序忽略原始消息中的空格,我希望得到:“isukzg wppannjqr”,但我得到:“isukzgwppannjqr”。任何人都知道我该如何解决这个问题。我考虑过使用 ords 但我还没有找到实现它的方法。代码如下:

def translateMessage(key, message, mode):
    translated = ""

    keyIndex = 0
    key = key.upper()

    for symbol in message:
        xyz = alphabet.find(symbol.upper())
        if xyz != -1:
            if mode == 'encrypt' or 'e':
                xyz += alphabet.find(key[keyIndex]) + 1
            elif mode == 'decrypt' or 'd':
                xyz -= alphabet.find(key[keyIndex]) + 1

            xyz %= len(alphabet)

            if symbol.isupper():
                translated += alphabet[xyz]
            elif symbol.islower():
                translated += alphabet[xyz].lower()

            keyIndex += 1
            if keyIndex == len(key):
                keyIndex = 0

    return translated

if __name__ == '__main__':
    fetch_user_inputs()

【问题讨论】:

您明确忽略了在alphabetxyz = alphabet.find(symbol.upper())if xyz != -1:)中找不到的所有符号,其中包括忽略空格。如果您忽略将其附加到输出中,为什么会期望在输出中有一个空格? 那我怎么只允许空格呢?我会使用 x.isspace() 吗? mode == 'decrypt' or 'd' 应该是 mode == 'decrypt' or mode == 'd'mode in ['decrypt', 'd']。也可以考虑'decrypt'.startswith(mode) @MadPhysicist 我试过这些,但我得到了一个语法错误。在测试这些时,我还注意到解密与加密相同。我不确定为什么这不起作用,因为我在解密 elif 之后有 xyz -= 我无法相信语法错误出现在 mutt 建议中。虽然您当前的语法是合法的,但它根本不像您看起来那样做。 【参考方案1】:

您只需要在translateMessage() 中添加一条else 语句,就可以像这样在输出中添加空格

def translateMessage(key, message, mode):
    translated = ""

    keyIndex = 0
    key = key.upper()

    for symbol in message:
        xyz = alphabet.find(symbol.upper())
        if xyz != -1:
            if mode == 'encrypt' or 'e':
                xyz += alphabet.find(key[keyIndex]) + 1
            elif mode == 'decrypt' or 'd':
                xyz -= alphabet.find(key[keyIndex]) + 1

            xyz %= len(alphabet)

            if symbol.isupper():
                translated += alphabet[xyz]
            elif symbol.islower():
                translated += alphabet[xyz].lower()

            keyIndex += 1
            if keyIndex == len(key):
                keyIndex = 0
        else : translated += symbol #this will add space as it is

    return translated

【讨论】:

【参考方案2】:

您可以做得更好,此代码甚至可以返回格式以及空格,例如。大写字母,小写字母!

def shift_dict(Caesar, Shift):
  dic_len = len(Caesar)
  Shift = Shift % dic_len
  list_dic = [(k,v) for k, v in iter(Caesar.items())]
  Shifted = 
    list_dic[x][0]: list_dic[(x - Shift) % dic_len][1]
    for x in range(dic_len)
  
  return Shifted

Viginere = 
  "A":0,
  "B":1,
  "C":2,
  "D":3,
  "E":4,
  "F":5,
  "G":6,
  "H":7,
  "I":8,
  "J":9,
  "K":10,
  "L":11,
  "M":12,
  "N":13,
  "O":14,
  "P":15,
  "Q":16,
  "R":17,
  "S":18,
  "T":19,
  "U":20,
  "V":21,
  "W":22,
  "X":23,
  "Y":24,
  "Z":25

VFU = 
  0:"A",
  1:"B",
  2:"C",
  3:"D",
  4:"E",
  5:"F",
  6:"G",
  7:"H",
  8:"I",
  9:"J",
  10:"K",
  11:"L",
  12:"M",
  13:"N",
  14:"O",
  15:"P",
  16:"Q",
  17:"R",
  18:"S",
  19:"T",
  20:"U",
  21:"V",
  22:"W",
  23:"X",
  24:"Y",
  25:"Z"

VFL = 
  0:"a",
  1:"b",
  2:"c",
  3:"d",
  4:"e",
  5:"f",
  6:"g",
  7:"h",
  8:"i",
  9:"j",
  10:"k",
  11:"l",
  12:"m",
  13:"n",
  14:"o",
  15:"p",
  16:"q",
  17:"r",
  18:"s",
  19:"t",
  20:"u",
  21:"v",
  22:"w",
  23:"x",
  24:"y",
  25:"z"


Asker = int(input("Do you want to... 1. Encode, or 2. Decode? "))
X = 0
Lister = []
Text = list(str(input("")))
Key = list(str(input("")).upper())
Z = 0

if Asker == 1:
  for i in range(len(Text)):
    Shift = Viginere[Key[(Z % len(Key))]]
    if Text[X].isalpha():
      LetterNum = Viginere[Text[X].upper()]
      Helper = (LetterNum + Shift) % 26
      if Text[X].isupper():
        Lister.append(VFU[Helper])
      else:
        Lister.append(VFL[Helper])
    else:
      Lister.append(Text[X])
      Z -= 1
    X += 1
    Z += 1
  print(*Lister, sep = "")
elif Asker == 2:
  for i in range(len(Text)):
    Shift = Viginere[Key[(Z % len(Key))]]
    if Text[X].isalpha():
      LetterNum = Viginere[Text[X].upper()]
      Helper = (LetterNum - Shift) % 26
      if Text[X].isupper():
        Lister.append(VFU[Helper])
      else:
        Lister.append(VFL[Helper])
    else:
      Lister.append(Text[X])
      Z -= 1
    X += 1
    Z += 1
  print(*Lister, sep = "")

这将轻松解决您的问题,它甚至会要求您输入字符串和密钥!这就是python魔法的定义。

【讨论】:

您可以通过VFU = dict((v, k) for k, v in Viginere.items())VFL = dict((v, k.lower()) for k, v in Viginere.items()) 使这更简洁

以上是关于如何让我的 Vigenère Cipher 忽略原始消息中的空格的主要内容,如果未能解决你的问题,请参考以下文章

维吉尼亚密码(Vigenère cipher)

JavaScript 中的 Vigenère 密码显示或 � 字符

C中的Vigenère密码,如何仅在字母字符上移动关键字

编码 Vigenère 密码时 c 中的分段错误

PHP 中的 Vigenère 表

Vigenère 密码,C 中的问题