当输出字符超出'z'时,凯撒密码失败

时间:2013-08-01 00:19:49

标签: python if-statement for-loop python-3.x encryption

为了清楚起见,我问这个是因为我已经尝试了大约1.5小时,似乎无法得到任何结果。我没有参加编程课程或其他什么,但今年夏天我有很多空闲时间,我正在使用它来学习本书中的python。我想知道如何完成这个问题。

问题要求您创建一个运行“caesar cipher”的程序,该程序将字符的ascii数字向下移动您选择的某个键。例如,如果我想编写sourpuss并选择2的密钥,程序将吐出所有向下移动两个的ascii字符。所以s会变成你,o会变成q(ascii字母下面的2个字符......)。

我可以通过编写这个程序来获得这一部分。

def main():
    the_word=input("What word would you like to encode? ")
    key=eval(input("What is the key? "))
    message=""
    newlist=str.split(the_word)
    the_word1=str.join("",the_word)
    for each_letter in the_word1:
        addition=ord(each_letter)+key
        message=message+chr(addition)
    print(message)
main()

运行此程序,您将获得以下内容:

What word would you like to encode? sourpuss
What is the key? 2
uqwtrwuu

现在,下一个问题是,如果您将密钥添加到ascii编号并导致数字高于128,则会出现问题。它会要求您创建一个实现的程序 一个系统,如果数字高于128,字母表将重置,你将返回到ascii值为0.

我试图做的是这样的事情:

if addition>128:
    addition=addition-128

当我在执行此操作后运行程序时,它不起作用,只返回一个空格而不是正确的字符。有任何想法吗?

3 个答案:

答案 0 :(得分:1)

英文字母中没有128个字符,所以你不应该用128减去。我不知道为什么你认为问题出现在128.英文字母的最后一个字符的序数是122.当你达到122时合理地发生问题。

此外,你没有处理大写和小写,但是,我猜,只要你总是使用小写,这是可以的。 : - )

你提到过“更多角色”。你可以做的是做一个二进制凯撒密码,它不关心你正在使用什么字符,但只是把它看作数字。

def cipher(text, key):
    return [(c + key) % 256 for c in text.encode('utf8')]

def decipher(data, key):
    return bytes([(c - key) % 256 for c in data]).decode('utf8')


if __name__ == "__main__":
    data = cipher("This is a test text. !^äöp%&ł$€", 101)
    print("Cipher data:", data)
    print("Text:", decipher(data, 101))

输出:

Cipher data: [185, 205, 206, 216, 133, 206, 216, 133, 198, 133, 217, 202, 216, 217, 133, 217, 202, 221, 217, 147, 133, 134, 195, 40, 9, 40, 27, 213, 138, 139, 42, 231, 137, 71, 231, 17]
Text: This is a test text. !^äöp%&ł$€

答案 1 :(得分:1)

尝试使用模运算而不是条件:

((ord('z') + 0 - 97) % 26) + 97
=> 122 # chr(122) == 'z'

((ord('z') + 1 - 97) % 26) + 97
=> 97 # chr(97) == 'a'

((ord('z') + 2 - 97) % 26) + 97
=> 98 # chr(98) == 'b'

请注意这个表达式:

((ord(character) + i - 97) % 26) + 97

在我们添加偏移character key ,就像你调用它)之后,返回代表给定i 的正确整数。特别是,如果我们将0添加到ord('z'),那么我们会返回'z'的代码。如果我们将1添加到ord('z'),那么我们会获得a的代码,依此类推。

这适用于a-z之间的小写字符,幻数97a的代码,26a之间的字符数和z;通过调整这些数字,您可以调整代码以支持更大范围的字符。

答案 2 :(得分:0)

尝试将此功能合并到您的代码中。这将做的是,如果你的凯撒密码的ascii数字高于z的ascii值,那么它将 - 26.例如,如果你的加法变量的值变为123,程序将减去26给你97给你'一个'。如果ascii值低于'a'的值,这也有效。

if addition > ord("z")
    addition -= 26
elif addition < ord("a"):
    addition+=26