chr() ord()输入空格ValueError: chr()参数不在(0x110000)范围内



我试图在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...nnnnnn") #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...nnnnnn") #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...nnnnnn") #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
如果有人能帮助我解决我面临的问题,我将非常感激!

如果纯文本字符和关键字都是空格(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():

最新更新