chr()ord()进入空格ValueError:chr()arg不在范围内(0x110000)

时间:2015-10-01 17:20:13

标签: python

我正在尝试在python中创建一个Vigenere Cypher并且遇到了这个问题(可能是我要么是盲目的还是只是愚蠢的!)并且需要一些帮助,主加密/解密功能正常但我正在尝试在输入消息和关键字中包含空格,当我尝试通过关键字“hello there”键入“hello there”时,它会给我输出

    crypt += chr(new)
ValueError: chr() arg not in range (0x110000)

这是我的代码:

import sys #This imports the "system" module, this allows me to safely close the code
accept_yes = ["YES", "Y"]
accept_no = ["NO", "N"]
accept_encrypt = ["ENCRYPT", "E"]
accept_decrypt = ["DEDCRYPT", "D"]
accept_exit = ["EXIT"] #These lists create a group of allowed inputs
def Task2(): #This defines a function so I can call it later in the code
    encrypt_or_decrypt = input("Do you wish to Encrypt, Decrypt or Exit?  ").upper() #This asks the user to type whether they would like to Encrypt, Decrypt or Exit the code
    if encrypt_or_decrypt in accept_encrypt: #This checks if the user input is one of the words inside the "accept_encrypt" list at the top of the code
        print("You chose Encrypt") #It then confirms the choice
    elif encrypt_or_decrypt in accept_decrypt:  #This checks if the user input is one of the words inside the "accept_decrypt" list at the top of the code
        print("You chose Decrypt") #It then confirms the choice
    elif encrypt_or_decrypt == ("EXIT"): #Then checks if the input was "Exit"
        print("Closing...\n\n\n\n\n\n") #If it was, tell the user that the code is closing
        sys.exit() #This shuts down the running code safely (made possible my the "import sys" at the top)
    else: #If the input was not in any of the lists above it will do the following
        print("Invalid Input") #Let the user know what has happened
        print("Try again") #And tells them to retry
        Task2() #It then calls the "Task2" function

    plaintext = input("Please enter the message you wish to Encrypt/Decrypt: ").upper() #This asks the user to input a message of their choice to encrypt/decrypt
    if not all(x.isalpha() or x.isspace() for x in plaintext): #This part checks if the "msg" variables has any spaces in it or has any numbers/symbols
        print("Invalid input") #If it does then 
        print("Try again")
        Task2()
    if len(plaintext) == 0: #This checks if the length of the input is 0 characters and if so...
        print("Invalid input length") #Tell them what happened
        print("Key must be of length 1 or more") #Explains what the problem was
        print("Please try again") #And lets them retry
        Task2() #Then calls the "Task2" function
    keyword  = input("Enter a key to offset your code: ").upper() #This asks for a different user input for the keyword to offset the previous message by
    if not all(x.isalpha() or x.isspace() for x in keyword): #This part checks if the "msg" variables has any spaces in it or has any numbers/symbols
        print("Invalid input") #If it does then 
        print("Try again")
        Task2()
    if len(keyword) == 0: #This checks if the length of the input is 0 characters and if so...
        print ("Invalid input length") #Tell them what happened
        print("Key must be of length 1 or more") #Explains what the problem was
        print("Please try again") #And lets them retry
        Task2() #Then calls the "Task2" function

    crypt = ('') #This sets a blank variable which will be altered to be the final message
    decrypt = ('') #This sets a different blank variable which will be altered to be the final message
    for n in range(0, len(plaintext)):
        new = ord(plaintext[n]) + ord(keyword[n%len(keyword)]) - 65 #This set the variable "new" as the ascii number of the message plus the ascii number of the keyword
        if new > 90: #This checks if the "new" variable is larger than 90...
            new -= 26 #If it is, minus 26 from what it was originally
        crypt += chr(new) #This makes "crypt" the ascii letter + the "new" value
        new = ord(plaintext[n]) - ord(keyword[n%len(keyword)]) + 65 #This set the variable "new" as the ascii number of the message minus the ascii number of the keyword
        if new < 65: #If the "new" variable value is less than 65...
            new += 26 #Make "new" 26 more than it was originally
        decrypt += chr(new) #And makes "decrypt" the ascii letter + the "new" value
    if encrypt_or_decrypt in accept_encrypt: #If they wanted to encrypt...
                print ("\nEncrypted message: " + crypt + "\n") #print the final message to the user
                Restart() #Calls the "Restart" function
    elif encrypt_or_decrypt in accept_decrypt: #If they wanted to decrypt...
                print ("\nDecrypted message: " + decrypt + "\n") #print the final message to the user
                Restart() #Calls the "Restart" function

def Restart(): #This defines a function so I can call it later in the code
    restart = input("Would you like to restart?\n").upper() #This asks the user if they want to restart
    if restart in accept_yes: #If the input is in the "accept_yes" list at the top of the code...
        print ("Restarting...\n\n\n\n\n\n") #Tell the user that the code is restarting
        Task2() #Then call the "Task2" function I defined
    elif restart in accept_no: #If the input is in the "accept_no" list at the top of the code...
        print ("Closing...\n\n\n\n\n\n") #Tell the user that the code is closing
        sys.exit() #Safely shuts down the running code
    else: #If the input was none of these...
        print ("Invalid Input") #Tell the user what the problem was
        Restart() #Calls the "Restart" function again

Task2() #This calls the actual encryption/decryption function

如果有人可以帮我解决我面临的问题,我会非常感激的!

1 个答案:

答案 0 :(得分:3)

如果纯文本字符和关键字都是空格(ASCII 32),则最终为负1:

>>> plain = keyword = ' '  # space is ASCII 32
>>> ord(plain) + ord(keyword) - 65  # 32 + 32 - 65
-1
>>> chr(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: chr() arg not in range(0x110000)

你必须考虑如何在你的密码中处理这种情况,或者完全剥离空间,这是传统上已经完成的。

如果您想要包含空格,只需将它们添加到密文并继续(有可能更容易破解您的代码):

for n in range(0, len(plaintext)):
    if plaintext[n] == ' ':
        crypt += ' '
        decrypt += ' '
        continue
    # your original loop body

另一个选择是禁止密钥中的空格;您将获得加密文本,其中明文中的空格被加密为空格,符号!"#$%&\'()*+,-.或数字0到9.为此,只需更改

if not all(x.isalpha() or x.isspace() for x in keyword):

if not keyword.isalpha():