Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 制作Vigen&xE9;重新加密/解密跳过空白_Python_Python 3.x_Encryption_Whitespace_Vigenere - Fatal编程技术网

Python 制作Vigen&xE9;重新加密/解密跳过空白

Python 制作Vigen&xE9;重新加密/解密跳过空白,python,python-3.x,encryption,whitespace,vigenere,Python,Python 3.x,Encryption,Whitespace,Vigenere,我用Vigenére密码制作了一个基于菜单的加密工具。到目前为止,该程序加密空白,我如何才能让程序跳过空白 #creating variables to be used text_in_use = '' encrypt_key = '' decrypt_key = '' #function to encypypt input text def encrypt(plaintext, key): keyLength = len(key) keyAsIntegers = [ord(i

我用Vigenére密码制作了一个基于菜单的加密工具。到目前为止,该程序加密空白,我如何才能让程序跳过空白

#creating variables to be used
text_in_use = ''
encrypt_key = ''
decrypt_key = ''

#function to encypypt input text
def encrypt(plaintext, key):
    keyLength = len(key)
    keyAsIntegers = [ord(i) for i in key] #create list with the ASCII value for each charachter in key
    plaintextAsIntegers = [ord(i) for i in plaintext] #create list with the ASCII value for each charachter in text
    encyptedtext = '' 
    for i in range(len(plaintextAsIntegers)): #
        encryptvalue = (plaintextAsIntegers[i] + keyAsIntegers[i % keyLength]) % 26 #execute encryption or characters according to vigenere definition
        encyptedtext += chr(encryptvalue + 65)
    return encyptedtext #return the encyptes tex

#function to decrypt the encrypted text
def decrypt(encyptedtext, key):
    keyLength = len(key)
    keyAsIntegers = [ord(i) for i in key] #create list with the ASCII value for each charachter in key
    encryptedTextAsIntegers = [ord(i) for i in encyptedtext] #create list with the ASCII value for each charachter in text
    plaintext = ''
    for i in range(len(encryptedTextAsIntegers)):
        value = (encryptedTextAsIntegers[i] - keyAsIntegers[i % keyLength]) % 26 #decryption of encrypted characters
        plaintext += chr(value + 65)
    return plaintext #return decrypted text

#check if user input is valid
def check_value(userEntry):
    while True:
        try: #check if userinput is an integer
            userInput = int(input(userEntry))
            if userInput not in range(1,6): #check if userinput is in valid range
                print("Invalid choice, valid choices are 1-5! Try again! \n")
        except ValueError:
            print("Invalid choice! Input can't be empty or a string! \n")
            print("""1: Input text to work with
2: Print the current text
3: Encrypt the current text
4: Decrypt the current text
5: Exit""")
        else:
            return userInput #return valid userinput


def menu():
    while True:
        print("""1: Input text to work with
2: Print the current text
3: Encrypt the current text
4: Decrypt the current text
5: Exit""")

        choice = check_value("Enter Choice: ")

        if choice == 1: #allows user to input text for use
            text_in_use = str(input("Enter Text: ")).upper()
            print("Text is set to:",text_in_use,"\n")
        elif choice == 2: #prints set text
            print("Your text:",text_in_use,"\n") 
        elif choice == 3: #ask user to set encryptionkey
            encrypt_key = str(input("Enter an encryptionkey: ")).upper()
            text_in_use = encrypt(text_in_use, encrypt_key)
            print("Your text:", text_in_use)
        elif choice == 4: #ask user for decryptionkey
            decrypt_key = str(input("Enter a the decryptionkey: ")).upper()
            text_in_use = decrypt(text_in_use, decrypt_key)
            print("Your text:", text_in_use)
        elif choice == 5:
            exit()

menu()
我希望程序能够像以前一样工作,但它应该跳过加密中的空白

例如:

“你好,我的人”-->加密(key=asd)-->“HWOLG MQ MSQ”
换句话说,在加密文本中应该仍然存在空格。

不确定当明文为“HELLO MY MAN”且密钥为“asd”时,如何获得“HWOLG MQ MSQ”。我还有别的事要做

无论如何,可能是这样的:

def encrypt(plaintext, key):
    from itertools import cycle
    from string import ascii_uppercase as alphabet

    offset = ord("A")

    key_char = cycle(key)

    encrypted_plaintext = ""
    for char in plaintext:
        # If the current character is any kind of whitespace...
        if char.isspace():
            # Append it to the final string with no changes.
            encrypted_plaintext += char
        else:
            # The character is not whitespace, so you have to encrypt it.
            char_sum = ord(char) + ord(next(key_char))
            char_sum_wrapped = char_sum % len(alphabet)
            encrypted_plaintext += chr(char_sum_wrapped + offset)
    return encrypted_plaintext
如果当前字符是空白,只需将其附加到最后一个字符串中,而不做任何更改<如果字符串(当前字符)中的每个字符都是某种空白(空格、制表符、换行符、回车符等),则code>str.isspace返回true

我尽量避免使用索引和硬编码数字,所以我改变了一些事情。例如,在执行其他操作之前,我没有像您那样将明文和密钥中的所有字符转换为整数,而是转换循环中的字符。顺便说一句,循环也是不同的-我在明文中迭代字符,而不是对循环执行基于范围的操作,然后将
I
作为当前字符的索引。其余的基本相同(除了
key\u char
itertools.cycle
内容,请阅读下面我的注释)

另一件需要注意的事情是,在这个实现中,只有当明文中的当前字符不是空白时,
key\u char
迭代器才会前进-但是,您可能希望它无论如何前进。只是要记住一些事情

别担心,这似乎是这个密码想要的行为

另外,请注意,您的程序从以下几行开始:

#creating variables to be used
text_in_use = ''
encrypt_key = ''
decrypt_key = ''
它们根本不起作用,您可以安全地移除它们

编辑-更多信息:

itertools.cycle
是一个函数,给定一个iterable(如字符串或列表),它返回一个迭代器,生成该iterable中的元素。例如:

>>> from itertools import cycle
>>> char_iterator = cycle("ABC")
>>> next(char_iterator)
'A'
>>> next(char_iterator)
'B'
>>> next(char_iterator)
'C'
>>> next(char_iterator)
'A'
>>> next(char_iterator)
'B'
>>> next(char_iterator)
'C'
>>> next(char_iterator)
'A'
>>> 
正如你所看到的,循环无限期地重复。出于这个原因,我选择使用
itertools.cycle
替换原始代码中的
keyAsIntegers[I%keyLength]

string.ascii_大写字母
只是一个由a-Z之间的所有大写字母组成的字符串。在我的代码中,我导入了
ascii_大写字母
,并在同一行将其重命名为
字母表
,但它们是相同的

>>> from string import ascii_uppercase as alphabet
>>> alphabet
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> 

您可以忽略空白的加密方法,或者重构代码,只对实际单词进行加密,例如使用
明文.split(“”)
获取要加密的单词列表,然后对列表中的每个项目运行加密/解密

下面是如何在加密过程中忽略空白。请注意,此实现假定通过“跳过空白”,意味着您通常仍会加密空白。空格仍然是关键,它不是完全正确的行为

def encrypt(plain_text, key):
    ...
    for i in range(len(plaintextAsIntegers)):
        if plain_text[i] == ' ':
            encryptedtext += ' '
        else:
            encryptvalue = (plaintextAsIntegers[i] + keyAsIntegers[i % keyLength]) % 26 
            encyptedtext += chr(encryptvalue + 65)
解密应该是相反的过程

...
if encryptedtext[i] == ' ':
    plain_text += ' ':
else:
...

这使得加密更弱,因为可以根据单词的长度猜出单词的长度。最好将所有空格(包括制表符等)作为一个字符进行加密。

加密的全部目的是使密码文本看起来尽可能随机。如果你保留空间,它会更容易破裂。不管怎样,常规算法也会加密空白,所以你要么修改算法,要么单独加密每个单词。这有一些重复,但这一个的措辞很好,而其他人似乎更为糟糕的代码/附加问题/更具体的代码特定问题,并且往往没有得到回答,因此kudo对此表示支持。但是,请特别注意标题的正确性,并在发布前查看您的帖子。我已经投了赞成票,但这个问题是不正确的,您需要保留一个单独的偏移量,以指示要使用的键中的下一个字符。请修复。@MaartenBodewes很确定他们用这段代码就是这么做的,不是吗
keyAsIntegers[i%keyLength]
…问题是,即使找到空间,
i
也会前进。人们通常认为维格纳不是这样运作的。密文应该是相同的,有空格或没有空格。至少在回答中应该注意到这一点,但老实说,我认为大多数学者认为目前的答案是错误的。这取决于你对“跳过”的解释tbh@MaartenBodewes更新为包含假设等,感谢您指出。很好,我绝对喜欢
isspace()
循环
。这使得代码更易于阅读,因为它解释了代码试图实现的目标。当然,对于一个可能不被期望的初学者来说:)嗨,你似乎知道你在说什么!然而,你能对代码中发生的事情发表一些评论吗?因为我是一个初学者,很难理解发生的事情,正如上面的评论所提到的:)谢谢你们的反馈。我用更多的信息更新了我的帖子。如果我能更清楚地解释什么,请告诉我。