在Python 3.4中创建一个Caesar Cipher程序,但功能不起作用

时间:2014-11-25 23:20:00

标签: function python-3.x encryption typeerror

目前,我正在创建一个Caesar Cipher,但它无法正常工作,任何人都可以提供帮助吗?代码如下。目前,如果程序第一次运行(如同,没有必须重新运行的程序),它可以正常工作,但是当重新运行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()

我尝试使用try,except和else命令在getKey()函数期间创建错误证明。它将尝试&#39;尝试&#39;要看到输入是否为int,如果是,则转到else,但如果它不是int,则它将重新运行该函数。如果重新运行该函数并输入int,则会给出以下错误:

这是一个有效的例子:

Do you wish to Encrypt of Decrypt? Enter E or D: E

Enter your message: Hello
Enter a key number (1-26): 5

Translation complete: Mjqqt

这是一个例子,因为没有输入int,必须重新运行getKey()函数:

Do you wish to Encrypt of Decrypt? Enter E or D: E

Enter your message: Hello
Enter a key number (1-26): H
Invalid Option. Please try again.
Enter a key number (1-26): 5

Traceback (most recent call last):

  File "C:\Python34\Encryptor2.py", line 54, in 
    runProgram()
  File "C:\Python34\Encryptor2.py", line 52, in runProgram
    translatedMessage = getTranslated(userChoice, message, key) #Runs function to translate message, using the choice, message and key variables)
  File "C:\Python34\Encryptor2.py", line 35, in getTranslated
    num += key

TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'

正如您所看到的,它重新运行我想要的功能,但是在将字符串添加到字符ord时会发生错误。

4 个答案:

答案 0 :(得分:0)

第一次调用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()

答案 1 :(得分:0)

将输入更改为raw_input

答案 2 :(得分:0)

只需使用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)

答案 3 :(得分:-1)

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

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

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)