Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.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 在使用Caesar密码加密文本的程序中获取错误_Python_Encryption - Fatal编程技术网

Python 在使用Caesar密码加密文本的程序中获取错误

Python 在使用Caesar密码加密文本的程序中获取错误,python,encryption,Python,Encryption,凯撒密码是一种简单的加密方法,它将字符移动到字符前面的多个位置。例如,旋转为1的ABC将是BCD。然而,在这个程序中,所有字符的列表包括随机顺序的特殊字符,即 1234567890-=qwertyuiopasdfghjklzxcvbnm,./~!@#$%^&*()_+|\\{}[]:;\'"QWERTYUIOPASDFGHJKLZXCVBNM 因此,它更像是一种自定义密码,但遵循Caesar密码的原理,可以使用我在同一文本上创建的两个函数(encode()和decode())来测试代码

凯撒密码是一种简单的加密方法,它将字符移动到字符前面的多个位置。例如,旋转为1的ABC将是BCD。然而,在这个程序中,所有字符的列表包括随机顺序的特殊字符,即

1234567890-=qwertyuiopasdfghjklzxcvbnm,./~!@#$%^&*()_+|\\{}[]:;\'"QWERTYUIOPASDFGHJKLZXCVBNM
因此,它更像是一种自定义密码,但遵循Caesar密码的原理,可以使用我在同一文本上创建的两个函数(encode()和decode())来测试代码,如果给定的输出与输入相同,则意味着它可以工作。我得到了一些旋转数的输出,但是一些数字,比如70,给了我一个错误。我写的代码是:

characters = '`1234567890-=qwertyuiopasdfghjklzxcvbnm,./~!@#$%^&*()_+|\\{}[]:;\'"QWERTYUIOPASDFGHJKLZXCVBNM' # All characters in a string, no specific order
key_raw = 70 # One of the keys that gives me an error.
def encode(text, key): # Function that takes in two inputs: Text and key, which is the number of characters to shift forward
    output, text = '', str(text)
    limit = len(characters)
    while key > limit:
        key -= limit # This is my attempt to simplify the key
    for i in text:
        if i in characters:
            output += characters[characters.index(i)+key] # If i is in characters, the rotated character is concatenated to the output
        else:
            output += i # Otherwise, it directly adds the text
    return output
def decode(text, key): # Same thing, except key is subtracted from the index of i in key, as to decrypt it
    output, text = '', str(text)
    limit = len(characters)
    while key > limit:
        key -= limit
    for i in text:
        if i in characters:
            output += characters[characters.index(i)-key]
        else:
            output += i
    return output
print(encode('Why do I get String_Index_Out_Of_Range?', key_raw))

请告诉我哪里出错了

考虑当您收到
字符时会发生什么。索引(i)+键
其中索引是
字符
中的最后一个符号

简单地说,您的凯撒密码缺少模运算

但是,为了使它更有用,我们仍然可以尝试进一步改进您的代码

让我们从构建字符串的方式开始。当前使用的是大字符串。相反,您应该尝试使用
.join()

现在,您的密钥优化基本上只是一个模运算,所以让我们用`key=key%len(字符)替换它

现在是查找方法。它希望
O(n)
复杂性,并且具有
O(nm)
复杂性。考虑到您可能会加密大文本,您可能需要交换一些空间以节省时间。让我们改用映射结构

然后再做一些收尾工作,让这个更漂亮

def encrypt(text:str, key:int, characters:str=characters): 
    '''
    Function that shifts input by the number of buckets specified in key.
    Unknown characters are retained.

    :param text: text to be encrypted
    :param key: number to shift by
    :param characters: string specifying character ordering, None for default.

    :return: encrypted string
    '''
    if not isinstance(text, str) or not isinstance(key, int):
        raise ValueError('Incorrect param type')

    output= []
    l = len(characters)
    key = key % l
    char_map = { characters[i]:((i+key) % l) for i in characters}
    for i in text:
        ch = char_map.get(i)
        if ch is None:
            ch = i
        output.append(ch)
    return output.join()

output+=字符[字符.索引(i)+键]


output+=字符[字符.索引(i)-键]

上面的行缺少模运算

字符。索引(i)+键
必须采用字符长度的模除,即代码中的
限制
。 所以应该是,


output+=characters[(characters.index(i)+key)%limit]


output+=characters[(characters.index(i)-key)%limit]

这应该对你有用

def encrypt(text:str, key:int): # Function that takes in two inputs: Text and key, which is the number of characters to shift forward
    output, text = [], str(text)
    key = key % len(characters)
    for i in text:
        if i in characters:
            output.append(characters[characters.index(i)+key]) # If i is in characters, the rotated character is concatenated to the output
        else:
            output.append(i) # Otherwise, it directly adds the text
    return output.join()
def encrypt(text:str, key:int, characters:str=characters): 
    '''
    Function that shifts input by the number of buckets specified in key.
    Unknown characters are retained.

    :param text: text to be encrypted
    :param key: number to shift by
    :param characters: string specifying character ordering, None for default.

    :return: encrypted string
    '''
    if not isinstance(text, str) or not isinstance(key, int):
        raise ValueError('Incorrect param type')

    output= []
    l = len(characters)
    key = key % l
    char_map = { characters[i]:((i+key) % l) for i in characters}
    for i in text:
        ch = char_map.get(i)
        if ch is None:
            ch = i
        output.append(ch)
    return output.join()