实现一个简单的移位密码,类似凯撒密码,以及一个更安全的替换密码。
“如果他有任何机密要说,就会用密码写下来,也就是把字母表中字母的顺序打乱,让人无法辨认出任何一个字。 如果有人想破译这些内容、弄清其中的含义,就必须用字母表中的第四个字母,即 D,替换 A,其余字母也依此类推。” 苏维托尼乌斯,《凯撒传》
加密是非常直接的算法,能让文本变得不那么易读,同时又便于解密。 它们容易受到多种密码分析手段的攻击,不过凯撒很幸运,他的敌人并不是密码分析专家。
凯撒密码曾被用于尤利乌斯·凯撒送到前线的部分消息。 凯撒知道这种密码并不算好,但在这一点上他有一个优势:几乎没有人能很好地阅读。 所以,哪怕差上几个字母,也足以让人们认不出他们本来认识的那几个词。
你的任务是创建一个类似凯撒密码的简单移位密码。 下图是凯撒密码的一个很好的示例:
![]()
例如:
把 "iamapandabear" 作为输入传给 encode 函数,会返回密文 "ldpdsdqgdehdu"。 它足够晦涩,能让我们的消息在传输途中保持保密。
把 "ldpdsdqgdehdu" 输入 decode 函数,它会返回原始的 "iamapandabear",让你的朋友能读懂你的原始消息。
一旦敌方指挥官破解了移位密码,它很快就失去用处。 所以,我们改用替换密码试试。 试着修改代码,让我们可以指定一个密钥,并用它来决定移位的距离。
下面是一个例子:
给定密钥 "aaaaaaaaaaaaaaaaaa",对字符串 "iamapandabear" 进行编码, 会返回原始的 "iamapandabear"。
给定密钥 "ddddddddddddddddd",对我们的字符串 "iamapandabear" 进行编码, 会返回经过掩饰的 "ldpdsdqgdehdu"
在上面的例子中,我们把密钥值设为 a = 0。 所以,当把明文加到密钥上时,得到的还是同一条消息。 因此,"aaaa" 并不是理想的密钥。 但如果把密钥设为 "dddd",得到的结果就和凯撒密码一样。
任何密码中最薄弱的环节都是人。 让我们给替换密码增加一点容错能力:提供一个随机源,并确保密钥只包含小写字母。
如果有人完全没有提供密钥,就生成一个真正随机的密钥,长度至少为 100 个小写字符。
移位密码通过让文本稍微变得古怪来起作用,但容易受到频率分析的影响。 替换密码能改善这一点,但在密钥很短或保留空格时,仍然非常脆弱。 之后,你会在 "crypto-square" 这个练习里看到这个问题的一种解决方案。
如果你想在这个领域走得更远,问题就开始围绕如何安全地交换密钥展开。 来看看维基百科上的 Diffie-Hellman,它是这一方案最早的实现之一。
当下标超出范围时,试着用求模这样的算术运算把它绕回来。Character 和 String 类同样是你的好帮手。