在 Python 3.4 中创建凯撒密码程序,但函数不起作用

Posted

技术标签:

【中文标题】在 Python 3.4 中创建凯撒密码程序,但函数不起作用【英文标题】:Creating a Caesar Cipher Program in Python 3.4, but function doesn't work 【发布时间】:2015-01-24 03:48:44 【问题描述】:

目前,我正在创建一个凯撒密码,但它无法正常工作,有人可以帮忙吗?代码将在下面。目前,如果程序第一次运行(如,没有函数必须重新运行)它可以完美运行,但是当 getKey() 函数重新运行时,它会返回错误。代码后,报错:

def runProgram():
    def choice():
        userChoice = input("Do you wish to Encrypt of Decrypt? Enter E or D: ").lower()
        if userChoice == "e":
            return userChoice
        elif userChoice == "d":
            return userChoice
        else:
            print("Invalid Response. Please try again.")
            choice()

    def getMessage():
        userMessage = input("Enter your message: ")
        return userMessage

    def getKey():
        try:
            userKey = int(input("Enter a key number (1-26): "))
        except:
            print("Invalid Option. Please try again.")
            getKey()
        else:
            if userKey < 1 or userKey > 26:
                print("Invalid Option. Please try again.")
                getKey()
            else:
                return userKey

    def getTranslated(userChoice, message, key):
        translated = ""
        if userChoice == "e":
            for character in message:
                num = ord(character)
                num += key
                translated += chr(num)

                savedFile = open('Encrypted.txt', 'w')
                savedFile.write(translated)
            savedFile.close()
            return translated
        else:
            for character in message:
                num = ord(character)
                num -= key
                translated += chr(num)
            return translated

    userChoice = choice() #Runs function for encrypt/decrypt selection. Saves choice made.
    message = getMessage() #Run function for user to enter message. Saves message.
    key = getKey() #Runs function for user to select key. Saves key choice.
    translatedMessage = getTranslated(userChoice, message, key) #Runs function to translate message, using the choice, message and key variables)
    print("\nTranslation complete: " + translatedMessage)
runProgram()

我尝试在 getKey() 函数中使用 try、except 和 else 命令创建它的错误证明。它将“尝试”查看输入是否为 int,如果是,则转到 else,但如果不是 int,则它将重新运行该函数。如果重新运行该函数,并输入一个 int,则会给出此错误:

这是它工作的一个例子:

你想加密解密吗?输入 E 或 D:E 输入您的信息:您好 输入密钥编号 (1-26):5 翻译完成:mjqqt

这是由于未输入 int 而必须重新运行 getKey() 函数的示例:

你想加密解密吗?输入 E 或 D:E 输入您的信息:您好 输入键号 (1-26):H 无效的选项。请再试一次。 输入密钥编号 (1-26):5 回溯(最近一次通话最后): 文件“C:\Python34\Encryptor2.py”,第 54 行,在 运行程序() 文件“C:\Python34\Encryptor2.py”,第 52 行,在 runProgram translateMessage = getTranslated(userChoice, message, key) #运行函数来翻译消息,使用choice、message和key变量) 文件“C:\Python34\Encryptor2.py”,第 35 行,在 getTranslated 数字 += 键 类型错误:+= 不支持的操作数类型:“int”和“NoneType”

如您所见,它也按照我的意愿重新运行该函数,但是将键添加到字符序时出现错误。

【问题讨论】:

【参考方案1】:

只需使用基本上为您加密或解密消息的 maketrans 和翻译功能。它们为问题提供了一个非常简短和有效的解决方案

message = input('enter message').lower()
offset = int(input('enter offset (enter a negative number to decrypt)'))
alphabet = 'abcdefghijklmnopqrstuvwxyz'
enc_alphabet = (alphabet[alphabet.index(alphabet[offset]):len(alphabet)])+ alphabet[0:offset]
data = str.maketrans(alphabet,enc_alphabet)
final_message = str.translate(message, data)
print(final_message)

【讨论】:

【参考方案2】:

将您的输入更改为 raw_input

【讨论】:

【参考方案3】:

这段代码真的不需要这么复杂,如果你只使用正则表达式,代码会短得多,但(在我看来)要好得多。

这是我为凯撒密码加密、解密和使用正则表达式转换用户选择创建的代码。

import re

def caesar(plain_text, shift):
    cipherText = ''
    for ch in plain_text:
      stayInAlphabet = ord(ch) + shift
      if ch.islower():
        if stayInAlphabet > ord('z'):
          stayInAlphabet -= 26
        elif stayInAlphabet < ord('a'):
          stayInAlphabet += 26
      elif ch.isupper():
        if stayInAlphabet > ord('Z'):
          stayInAlphabet -= 26
        elif stayInAlphabet < ord('A'):
          stayInAlphabet += 26
      finalLetter = chr(stayInAlphabet)
      cipherText += finalLetter
    print(cipherText)
    return cipherText


selection = input ("encrypt/decrypt ")
if selection == 'encrypt':
  plainText = input("What is your plaintext? ")
  shift = (int(input("What is your shift? ")))%26
  caesar(plainText, shift)

else:
  plainText = input("What is your plaintext? ")
  shift = ((int(input("What is your shift? ")))%26)*-1
  caesar(plainText, shift)

【讨论】:

【参考方案4】:

第一次调用 getKey(),并附上您的评论:

key = getKey() #Runs function for user to select key. Saves key choice.

另一个你称之为的地方:

        if userKey < 1 or userKey > 26:
            print("Invalid Option. Please try again.")
            getKey()

如果你用同样的评论来写,那就是:

            getKey() #Runs function for user to select key. Doesn't save key choice.

用户输入的内容来自 getKey() ...而您没有跟踪它,所以它消失了。然后你做。

            return userKey

userKey 仍然是您尝试转换为 int 的 H,即失败的那个。你没有摆脱它,所以它仍然存在。

更好的解决方案是修改代码的形状,因此 getKey() 永远不会在其内部调用 getKey()。在外面做错误检查,也许像这种形状:

def getKey():
    prompt user for key
    try to convert to int and return the int
    if it fails, return None as an indication that getting the key went wrong.

key = None  #set some wrong placeholder
while (key is None) or (key < 1) or (key > 26):
    key = getKey()

【讨论】:

我以前从未使用过 return 命令,因此从未意识到会发生这种情况。谢谢,它真的很有帮助,现在工作正常!

以上是关于在 Python 3.4 中创建凯撒密码程序,但函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Python 凯撒密码解码器

7-30 jmu-python-凯撒密码加密算法 (10 分)

python-凯撒密码加解密

Python凯撒密码和反密码

基于python实现暴力破解凯撒密码

用python实现凯撒密码