我的 Python Caesar Cipher 程序在 30 后停止移动
My Python Caeser Cipher program stops shifting after 30
我创建了一个函数来将输入的字符串拆分为单词列表,然后将每个单词中的字母替换为其移位后的对应字母,但是当我将移位设置为超过 30 时,它的打印结果不变。
def ceaser_cipher_encoder(string , num):
alphabet = ["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"]
new_string = ""
string_list = string.split(" ")
new_list = []
for word in string_list:
word1 = ""
for charecter in word:
letter_position = alphabet.index(charecter)
letter_position_with_shift = letter_position + num
if letter_position_with_shift > 25:
letter_position_with_shift = 0 + ((letter_position - 25) - 1)
word1 += charecter.replace(charecter, alphabet[letter_position_with_shift])
new_list.append(word1)
end_string = " ".join(new_list)
return end_string
message = ceaser_cipher_encoder("hello dad", 35)
print(message)
此处一个有用的技巧是使用 模数 运算符 (%
)。它将为您处理轮班。
这是我的做法:
def ceaser_cipher_encoder(string , num):
alphabet = ["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"]
new_string = ""
for c in string:
new_string += alphabet[(alphabet.index(c) + num) % len(alphabet)]
return new_string
假设 c
是“y”,num
是 10。那么 alphabet.index(c)
等于 24,所以移位会 return 34。因为34 模 26 是 8,它会将 alphabet[8]
("i") 附加到 new_string
.
我使用 len(alphabet)
而不是硬编码 26,这样您可以更改字母表并且代码仍然有效。
问题出在你的 if 语句上:
if letter_position_with_shift > 25:
letter_position_with_shift = 0 + ((letter_position - 25) - 1)
真的应该是:
if letter_position_with_shift > 25:
letter_position_with_shift = 0 + ((letter_position_with_shift - 25) - 1)
也就是说,最好在这里使用 modolo operator 而不是 if 语句来处理 26 的任何倍数,而不仅仅是 26-52。例如,考虑 num = 100 的情况。
尝试将您的 for 循环体更改为:
letter_position = alphabet.index(charecter)
letter_position_with_shift = (letter_position + num) % 26
word1 += charecter.replace(charecter, alphabet[letter_position_with_shift])
我还建议将最后一行替换为:
word1 += alphabet[letter_position_with_shift]
因为您无论如何都要将该字母附加到 word1
,所以您实际上不需要调用字符替换来获取字母表[letter_position_with_shift]
如果你想让你的代码更短一点,那么你可以试试这个:
def cipher(plain: str, offset: int) -> str:
abc = 'abcdefghijklmnopqrstuvwxyz'
return plain.translate(str.maketrans({c: abc[(idx + offset) % len(abc)] for idx, c in enumerate(abc)}))
print(cipher("hello dad", 35)) # Output: qnuux mjm
进一步阅读:
我创建了一个函数来将输入的字符串拆分为单词列表,然后将每个单词中的字母替换为其移位后的对应字母,但是当我将移位设置为超过 30 时,它的打印结果不变。
def ceaser_cipher_encoder(string , num):
alphabet = ["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"]
new_string = ""
string_list = string.split(" ")
new_list = []
for word in string_list:
word1 = ""
for charecter in word:
letter_position = alphabet.index(charecter)
letter_position_with_shift = letter_position + num
if letter_position_with_shift > 25:
letter_position_with_shift = 0 + ((letter_position - 25) - 1)
word1 += charecter.replace(charecter, alphabet[letter_position_with_shift])
new_list.append(word1)
end_string = " ".join(new_list)
return end_string
message = ceaser_cipher_encoder("hello dad", 35)
print(message)
此处一个有用的技巧是使用 模数 运算符 (%
)。它将为您处理轮班。
这是我的做法:
def ceaser_cipher_encoder(string , num):
alphabet = ["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"]
new_string = ""
for c in string:
new_string += alphabet[(alphabet.index(c) + num) % len(alphabet)]
return new_string
假设 c
是“y”,num
是 10。那么 alphabet.index(c)
等于 24,所以移位会 return 34。因为34 模 26 是 8,它会将 alphabet[8]
("i") 附加到 new_string
.
我使用 len(alphabet)
而不是硬编码 26,这样您可以更改字母表并且代码仍然有效。
问题出在你的 if 语句上:
if letter_position_with_shift > 25:
letter_position_with_shift = 0 + ((letter_position - 25) - 1)
真的应该是:
if letter_position_with_shift > 25:
letter_position_with_shift = 0 + ((letter_position_with_shift - 25) - 1)
也就是说,最好在这里使用 modolo operator 而不是 if 语句来处理 26 的任何倍数,而不仅仅是 26-52。例如,考虑 num = 100 的情况。
尝试将您的 for 循环体更改为:
letter_position = alphabet.index(charecter)
letter_position_with_shift = (letter_position + num) % 26
word1 += charecter.replace(charecter, alphabet[letter_position_with_shift])
我还建议将最后一行替换为:
word1 += alphabet[letter_position_with_shift]
因为您无论如何都要将该字母附加到 word1
,所以您实际上不需要调用字符替换来获取字母表[letter_position_with_shift]
如果你想让你的代码更短一点,那么你可以试试这个:
def cipher(plain: str, offset: int) -> str:
abc = 'abcdefghijklmnopqrstuvwxyz'
return plain.translate(str.maketrans({c: abc[(idx + offset) % len(abc)] for idx, c in enumerate(abc)}))
print(cipher("hello dad", 35)) # Output: qnuux mjm
进一步阅读: