初学者使用凯撒密码并遇到非完整输入特定的问题

问题描述 投票:0回答:1

我正在研究凯撒密码,但在加密部分遇到了大问题!

我的代码:

direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
text = input("Type your message:\n").lower()
shift = int(input("Type the shift number:\n"))

message = []
def caesar(text, shift):
  message = list(text)
  if shift > 26:
    shift = shift % 26
  for i in message:
    if i in alphabet:
      position = message.index(i)
      location = alphabet.index(i)
      if direction == "decode":
        shift = shift * -1
      newlet = alphabet[location + shift] 
      message.insert(position,newlet)
      message.remove(i)
      print(message)

老师的正确代码:

direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
text = input("Type your message:\n").lower()
shift = int(input("Type the shift number:\n"))

def caesar(text, shift):
  end_text = ""
  if direction == "decode":
    shift *= -1
  for char in text:
    if char in alphabet:
      position = alphabet.index(char)
      new_position = position + shift
      end_text += alphabet[new_position]
    else:
      end_text += char
  print(f"Here's the {direction}d result: {end_text}")

例如,当老师的文本输入是:“Taylor Swift”,shift 输入为 4 时,它显示为“xecpsv wamjx”,但我的显示为“xecpav swmjx”。

我尝试过切换各种东西,但我只是想了解出了什么问题以及为什么故障如此零星 - 有时它适用于较短的输入(例如“两个一”),但不适用于较长的输入(例如“文明”)或者反之亦然。非常混乱!

我将在下面添加一个程序运行输出的示例:我让它在每个循环运行时打印位置(单个数字)和消息(列表),这样我就可以看到发生了什么 - 位置被搞乱了,并且消息也是如此。

Type 'encode' to encrypt, type 'decode' to decrypt:
encode
Type your message:
taylor swift
Type the shift number:
4
0
['x', 'a', 'y', 'l', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
1
['x', 'e', 'y', 'l', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
2
['x', 'e', 'c', 'l', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
3
['x', 'e', 'c', 'p', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
4
['x', 'e', 'c', 'p', 's', 'r', ' ', 's', 'w', 'i', 'f', 't']
5
['x', 'e', 'c', 'p', 's', 'v', ' ', 's', 'w', 'i', 'f', 't']
4
['x', 'e', 'c', 'p', 'w', 'v', ' ', 's', 'w', 'i', 'f', 't']
4
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'i', 'f', 't']
9
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'm', 'f', 't']
10
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'm', 'j', 't']
11
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'm', 'j', 'x']
The encoded text is xecpav swmjx
python python-3.x encryption caesar-cipher
1个回答
0
投票

测试您的算法以及教师代码示例会在使用示例字符串运行测试时产生问题,因为两个示例代码块都不包含“alphabet”变量的值。

Traceback (most recent call last):
  File "/home/craig/Python_Programs/Caesar/CaesarOld.py", line 24, in <module>
    caesar(text, shift)
  File "/home/craig/Python_Programs/Caesar/CaesarOld.py", line 14, in caesar
    newlet = alphabet[location + shift] 
IndexError: string index out of range

使用名为“alphabet”且值为“abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz”的变量提供了解决此问题的方法。这样,我也收到了与您指出的相同的输出。参考好的评论,让您困惑的是使用“消息”列表中的列表索引功能,因为该列表不断被修改。为了说明这个问题,下面是带有函数重构版本的代码,添加了“print”语句来表示意外行为。

alphabet = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"   # Educated guess of this string

message = []
def caesar(text, shift):
  message = list(text)
  if shift > 26:
    shift = shift % 26
  for i in message:
    if i in alphabet:
      position = message.index(i)
      location = alphabet.index(i)
      if direction == "decode":
        shift = shift * -1
      newlet = alphabet[location + shift] 
      print("First occurance of", i, " is", position, " and now is", newlet) # Note value changes
      message.insert(position,newlet)
      message.remove(i)
      print(message)

direction = input("Type 'encode' to encrypt, type 'decode' to decrypt: ")
text = input("Type your message: ").lower()
shift = int(input("Type the shift number: "))

caesar(text, shift)

这提供了如何识别和修改列表中的字符的输出。

craig@Vera:~/Python_Programs/Caesar$ python3 CaesarOld.py 
Type 'encode' to encrypt, type 'decode' to decrypt: encode
Type your message: Taylor Swift
Type the shift number: 4
First occurance of t  is 0  and now is x
['x', 'a', 'y', 'l', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
First occurance of a  is 1  and now is e
['x', 'e', 'y', 'l', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
First occurance of y  is 2  and now is c
['x', 'e', 'c', 'l', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
First occurance of l  is 3  and now is p
['x', 'e', 'c', 'p', 'o', 'r', ' ', 's', 'w', 'i', 'f', 't']
First occurance of o  is 4  and now is s                        <--------- change of 'o' to 's'
['x', 'e', 'c', 'p', 's', 'r', ' ', 's', 'w', 'i', 'f', 't']
First occurance of r  is 5  and now is v
['x', 'e', 'c', 'p', 's', 'v', ' ', 's', 'w', 'i', 'f', 't']
First occurance of s  is 4  and now is w                        <--------- now the first 's' is being changed to 'w'
['x', 'e', 'c', 'p', 'w', 'v', ' ', 's', 'w', 'i', 'f', 't']
First occurance of w  is 4  and now is a                        <--------- now that 'w' is being changed to 'a'
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'i', 'f', 't']
First occurance of i  is 9  and now is m
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'm', 'f', 't']
First occurance of f  is 10  and now is j
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'm', 'j', 't']
First occurance of t  is 11  and now is x
['x', 'e', 'c', 'p', 'a', 'v', ' ', 's', 'w', 'm', 'j', 'x']
craig@Vera:~/Python_Programs/Caesar$ 

如上所述,当识别出“Taylor”中的字符“o”并发生移位时,该字符将更改为字符“s”。稍后,当遇到“Swift”中的字符“s”时,将在列表中搜索该字符的第一次出现,即现在的第五个字符,因此该字符通过移位值更改为字符“w” 。并且,“Swift”中的 's' 没有改变。随后,处理的下一个字符是“Swift”中的“w”字符。再次,使用列表索引功能,该字符的第一次出现是第五个字符,并且随后被移位/改变为字符“a”。同样,实际的角色并没有改变。这最终就是收到输出的原因。

利用老师的功能,这里是重构后的程序,并添加了一些注释进行解释。

alphabet = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"             # Educated guess of alphabetical string

def caesar(text, shift):
  end_text = ""
  if direction == "decode":
    shift *= -1
  for char in text:
    if char in alphabet:
      position = alphabet.index(char)       # Finds alphabetical position of the text character
      new_position = position + shift       # Stores the shifted character in a new work variable
      end_text += alphabet[new_position]    # Appends the new character in the text
    else:
      end_text += char
  print(f"Here's the {direction}d result: {end_text}")

direction = input("Type 'encode' to encrypt, type 'decode' to decrypt: ")
text = input("Type your message: ").lower()
shift = int(input("Type the shift number: "))

caesar(text, shift)

以下是一些亮点。

  • 在评估文本字符串中的每个字符时,将在字母字符串中搜索文本字符的位置。
  • 一旦位置确定,产生的移位字符将存储在单独的工作变量中。
  • 然后将该工作变量附加到新字符串 (end_text)。

处理完所有文本字符后,将打印生成的编码/解码文本。以下是对文本编码和解码的测试。

craig@Vera:~/Python_Programs/Caesar$ python3 Caesar.py
Type 'encode' to encrypt, type 'decode' to decrypt: encode
Type your message: Taylor Swift
Type the shift number: 4
Here's the encoded result: xecpsv wamjx
craig@Vera:~/Python_Programs/Caesar$ python3 Caesar.py
Type 'encode' to encrypt, type 'decode' to decrypt: decode
Type your message: xecpsv wamjx
Type the shift number: 4
Here's the decoded result: taylor swift

从中学到的主要内容可能是深入研究 Python 教程文献,特别是它涉及使用字符串和列表的索引函数。并且,在重用变量、列表等时要小心。

© www.soinside.com 2019 - 2024. All rights reserved.