python - 在使用凯撒密码加密文本的程序中出现错误
问题描述
Caesar Cipher 是一种简单的加密方法,可以将字符前面的多个位置移动。例如,旋转为 1 的 ABC 将是 BCD。然而,在这个程序中,所有字符的列表都包含随机顺序的特殊字符,即
1234567890-=qwertyuiopasdfghjklzxcvbnm,./~!@#$%^&*()_+|\\{}[]:;\'"QWERTYUIOPASDFGHJKLZXCVBNM
因此,它更像是一种自定义密码,但遵循凯撒密码的原则,可以使用我在同一文本上制作的 2 个函数(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))
请让我知道我在哪里犯了错误。
解决方案
考虑当您收到characters.index(i)+key
where index is the last symbol in时会发生什么characters
。
简而言之,您的凯撒密码缺少模运算。
但是,为了使它更有用,我们仍然可以尝试进一步改进您的代码。
让我们从构建字符串的方式开始。当涉及到大字符串时,您当前使用的速度较慢。相反,您应该尝试使用.join()
.
def encrypt(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.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()
现在你的键优化基本上只是一个模运算,所以让我们用 `key = key % len(characters) 替换它。
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()
现在是您的查找方法。它希望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()
推荐阅读
- r - 如何使用 fsolve 函数在 R 中找到多个非线性方程的解
- spring - 如何将 Thymeleaf 前端与 Spring Boot 项目分离
- xaml - 如何在 DirectX UWP 应用中呈现 XAML 页面
- wordpress - 如何从 Wordpress 搜索结果中排除特定页面
- android - 我的 JobService 在 Android 10 中无法运行,但在 Android 9 及更低版本中运行良好
- reactjs - 如何在 Reactjs 中创建多步表单
- java - 为 Spring Cloud 配置 maven 依赖项
- r - 在 R 4.0.0 之前安装了包“stringr”:请重新安装 BiocManager 安装路径不可写,无法更新包
- node.js - nodejs multer image upload:保留文件名和扩展名
- tensorflow - TensorFlow 和 Cuda 不兼容