我的 vigenere 密码加密功能有什么问题?
What's wrong with my vigenere cypher encrypt function?
我在加密函数中得到错误字符串索引超出范围我不知道如何让 rot 重复文本。该代码仅在两个输入长度相同时才有效。如果可以的话,我想保持 alphabet_position 和 rotate_character 功能相同。
alpha_lower_list = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
alpha_upper_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
def alphabet_position(letter):
if letter in alpha_upper_list:
return alpha_upper_list.index(letter)
else:
return alpha_lower_list.index(letter)
def rotate_character(char, rot):
rotated_letter = ''
if char.isalpha():
rotate = alphabet_position(char) + rot
if rotate < 26:
if char in alpha_upper_list:
rotated_letter = alpha_upper_list[rotate]
return(rotated_letter)
else:
rotated_letter = alpha_lower_list[rotate]
return(rotated_letter)
else:
if char in alpha_upper_list:
rotated_letter = alpha_upper_list[rotate % 26]
return(rotated_letter)
else:
rotated_letter = alpha_lower_list[rotate % 26]
return(rotated_letter)
else:
return(char)
def encrypt(text, rot):
lis = []
for i in range(len(text)):
lis.append(rotate_character(text[i], alphabet_position(rot[i])))
return (''.join(lis))
def main():
user_text = input("Type a message: ")
rotate_by = input("Rotate by: ")
print(encrypt(user_text, rotate_by))
if __name__ == '__main__':
main()
您在程序的第 36 行中使用 rot[i]
中的迭代器将越界 - i
将达到明文的长度,可以大于钥匙。
尝试按密钥的长度做一个模块-div,这样你应该很好地环绕密钥:
lis.append(rotate_character(text[i], alphabet_position(rot[i % len(rot)])))
编辑您对脚本返回的结果仍然不满意,所以我进行了更深入的研究。潜在的问题是您正在尝试实现一些维吉内尔在线工具调用 "enhanced mode":明文和密文都不能保证来自 [a-zA-Z]
,但可能 "special characters",例如来自 [0-9]
的元素或 <space>
、<
等字符
如果您的脚本遇到特殊字符,它不会旋转它,而是按原样复制它,就像在 rotate_character
的 else
分支中所做的那样;这是对的。然而,在 encrypt()
中,你会为你遇到的明文的 每个 符号消耗我们称之为 "keysymbol" 的东西。这意味着实际上你是 "wasting" 纯文本符号 上的一个密钥符号,根本不会被加密(vulgo 旋转)。
一旦你意识到这一点,解决办法就很明显了:当我们遇到一个特殊字符时,将它复制到输出列表中,但不要推进密钥流。仅当我们确实需要使用密钥符号时才应推进密钥流。
翻译成代码:
def encrypt(text, rot):
lis = []
keystream = 0
for i in range(len(text)):
keychar = keystream % len(rot)
if text[i].isalpha():
lis.append(rotate_character(text[i], alphabet_position(rot[keychar])))
keystream += 1
else:
lis.append(text[i])
return (''.join(lis))
我在加密函数中得到错误字符串索引超出范围我不知道如何让 rot 重复文本。该代码仅在两个输入长度相同时才有效。如果可以的话,我想保持 alphabet_position 和 rotate_character 功能相同。
alpha_lower_list = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
alpha_upper_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
def alphabet_position(letter):
if letter in alpha_upper_list:
return alpha_upper_list.index(letter)
else:
return alpha_lower_list.index(letter)
def rotate_character(char, rot):
rotated_letter = ''
if char.isalpha():
rotate = alphabet_position(char) + rot
if rotate < 26:
if char in alpha_upper_list:
rotated_letter = alpha_upper_list[rotate]
return(rotated_letter)
else:
rotated_letter = alpha_lower_list[rotate]
return(rotated_letter)
else:
if char in alpha_upper_list:
rotated_letter = alpha_upper_list[rotate % 26]
return(rotated_letter)
else:
rotated_letter = alpha_lower_list[rotate % 26]
return(rotated_letter)
else:
return(char)
def encrypt(text, rot):
lis = []
for i in range(len(text)):
lis.append(rotate_character(text[i], alphabet_position(rot[i])))
return (''.join(lis))
def main():
user_text = input("Type a message: ")
rotate_by = input("Rotate by: ")
print(encrypt(user_text, rotate_by))
if __name__ == '__main__':
main()
您在程序的第 36 行中使用 rot[i]
中的迭代器将越界 - i
将达到明文的长度,可以大于钥匙。
尝试按密钥的长度做一个模块-div,这样你应该很好地环绕密钥:
lis.append(rotate_character(text[i], alphabet_position(rot[i % len(rot)])))
编辑您对脚本返回的结果仍然不满意,所以我进行了更深入的研究。潜在的问题是您正在尝试实现一些维吉内尔在线工具调用 "enhanced mode":明文和密文都不能保证来自 [a-zA-Z]
,但可能 "special characters",例如来自 [0-9]
的元素或 <space>
、<
等字符
如果您的脚本遇到特殊字符,它不会旋转它,而是按原样复制它,就像在 rotate_character
的 else
分支中所做的那样;这是对的。然而,在 encrypt()
中,你会为你遇到的明文的 每个 符号消耗我们称之为 "keysymbol" 的东西。这意味着实际上你是 "wasting" 纯文本符号 上的一个密钥符号,根本不会被加密(vulgo 旋转)。
一旦你意识到这一点,解决办法就很明显了:当我们遇到一个特殊字符时,将它复制到输出列表中,但不要推进密钥流。仅当我们确实需要使用密钥符号时才应推进密钥流。
翻译成代码:
def encrypt(text, rot):
lis = []
keystream = 0
for i in range(len(text)):
keychar = keystream % len(rot)
if text[i].isalpha():
lis.append(rotate_character(text[i], alphabet_position(rot[keychar])))
keystream += 1
else:
lis.append(text[i])
return (''.join(lis))