运行python 3.5。 我开始研究基本加密,我决定尝试编写一个简单的Caesar密码。很直接的逻辑:
1)对于给定的纯文本消息,在我的LETTERS字符串中找到每个消息符号的索引
2)将shift键添加到索引
3)结果数字是密码符号的索引
4)如果结果数字大于我的LETTERS字符串的长度,则从数字中减去LETTERS字符串的长度(这会将回绕处理回到字符串的开头。
所以这是该程序的代码。
caesarCipher2.py
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrustuvwxyz1234567890!@#$%^&*()><.,?/"
message = str(input("Enter a message. "))
key = int(input("Enter a whole number key (1-79). "))
mode = str(input("Press 'E' to encrypt or 'D' to decrypt. "))
def encrypt_message(plain_message):
translated = " "
for symbol in plain_message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
num += key
if num > len(LETTERS):
num -= len(LETTERS)
translated += LETTERS[num]
else:
translated += symbol
return translated
def decrypt_message(cipher_message):
translated = " "
for symbol in cipher_message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
num -= key
if num < 0:
num += len(LETTERS)
translated += LETTERS[num]
else:
translated += symbol
return translated
def main():
if mode == "E" or mode == "e":
print(encrypt_message(message))
elif mode == "D" or mode == "d":
print(decrypt_message(message))
if __name__ == "__main__":
main()
程序似乎工作正常,但是当我运行测试用例时,我开始注意到某些shift键在encrypt_Message()的以下行抛出一个IndexError:
translated += LETTERS[num]
所以我决定编写另一个脚本,使用encrypt_Message()中的代码来测试所有可能键的任何给定消息。我发现的是,我通过函数传递的任何明文消息都会导致一些shift键(通常是5-10个键)在同一行抛出一个IndexError。所有其余的键都按预期返回密文。
调试这些错误抛出键上的代码向我展示了在翻译这些特定键的明文消息时的一些观点,即:
num = LETTERS.find(symbol)
返回LETTERS的长度而不是LETTERS中符号的索引,然后代码似乎从那里挂起。 if语句不会触发调整num变量,因此当它到达翻译语句时,num变量的索引超出范围。
我的问题是为什么会发生这种情况?为什么代码对大多数密钥起作用,同时为剩余的密钥抛出此异常?
有什么想法? 感谢。
答案 0 :(得分:2)
Python索引列表从0开始。这将产生以下影响:
>>> x = ['a', 'b', 'c', 'd']
>>> len(x)
4
>>> x[0]
'a'
>>> x[3]
'd'
>>> x[4]
IndexError: list index out of range
请注意,x[4]
已超出包含4个元素的列表的范围。根据经验,可以考虑的最大索引是len(x) - 1
。
在你的情况下,错误是
if num > len(LETTERS):
应该是
if num >= len(LETTERS):