我正在尝试在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
如果有人可以帮我解决我面临的问题,我会非常感激的!
答案 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():