Caesar密码的生成与破解
背景
在密码学中,恺撒密码(英语:Caesarcipher),或称恺撒加密、恺撒变换、变换加密,是一种最简单且最广为人知的加密技术。它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。这个加密方法是以罗马共和时期恺撒的名字命名的,当年恺撒曾用此方法与其将军们进行联系。
恺撒密码的替换方法是通过排列明文和密文字母表,密文字母表示通过将明文字母表向左或向右移动一个固定数目的位置。例如,当偏移量是左移3的时候(解密时的密钥就是3):
明文字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ ;
密文字母表:DEFGHIJKLMNOPQRSTUVWXYZABC。
使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。需要解密的人则根据事先已知的密钥反过来操作,得到原来的明文。例如:
明文:THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG ;
密文:WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ。
思路
加密
- 首先读入密钥和明文
- 然后将明文(字母)逐位循环右移k位
- 输出密文
解密
- 首先读入密文
- 然后穷举所有可能的密钥(26种)
- 对于每一个密钥对密文做循化左移
- 对处理后的句子做分割,分隔符是处理字母以外的其他符号
- 判断得到的单词在字典里面是否能找到,并统计每一句里面的个数
- 最后含有最多可识别单词的句子即为明文
- 输出破解出明文和密钥
实现
加密
'''
此程序用来做Caesar密码的加密工作
输入明文和密钥则可以生成对应的密文
原理是:明文的每一位字符都在字母表上循环右移key位
'''
key = int(input("请输入密钥(0~25之间的整数):\t"))
# key=1
plaintext = input("请输入要加密的明文:\t")
# plaintext="abcxyz ABCXYZ" # 测试用
# 此处可添加key和text的格式检查
print("\n您输入的key为:",key)
print("您输入的明文是:", plaintext, "\n") # 输入的明文可以包含任意非换行符的字符 但除大小写字母外 均被认为是分隔符
secrettext = [] # 字符串不可修改 用列表转换而来
for i in plaintext: # 依次处理字符串中的每个字符
if i.isalpha(): # 是字母才处理
if i.islower(): # 判断是小写字母
i = chr((ord(i) - 97 - key) % 26 + 97) # 小写字母 循环右移 key位
else:
i = chr((ord(i) - 65 - key) % 26 + 65) # 大写字母 循环右移 key位
secrettext.append(i)
secrettext="".join(secrettext) # 列表转换成字符串
print("变化后的密文是:",secrettext)
解密
'''
此程序用来做Caesar密码的解密工作
输密文可以破解出对应的密钥和明文
原理是:暴力穷举所有可能的key 对照字典查看哪种情况的文本最规范 则认为其是答案
'''
import enchant
d = enchant.Dict("en_US") #用来查询的字典
real_key = 0 # 密钥
plaintext = "" # 明文
secrettext = input("请输入要解密的密文:\t")
tmp = 0
for key in range(26):
in_plaintext = []
for i in secrettext: # 依次处理字符串中的每个字符
if i.isalpha(): # 是字母才处理
if i.islower(): # 判断是小写字母
i = chr((ord(i) - 97 + key) % 26 + 97)
else:
i = chr((ord(i) - 65 + key) % 26 + 65)
else:
i = " " # 不是字母的统一当作界符 并用空格统一替换
in_plaintext.append(i)
in_plaintext = "".join(in_plaintext)
in_plaintext_s = in_plaintext.split(" ") # 以空格区分单词
accuracy = 0 # 命中率 转换成明文之后 句子中可识别的单词
for word in in_plaintext_s:
if word != "":
accuracy += d.check(word) # 在词典中查询单词是否存在
if accuracy > tmp: # 找到命中率最高的一个key 即为最终答案
tmp = accuracy
real_key = key
plaintext = in_plaintext
# 下面输出每个key 对应的命中率 以及翻译出的明文 不需要可以注释掉
print("key:", str(key).center(3, " "), "\taccuracy:", accuracy, "\tplaintext: ", in_plaintext)
print("\nkey:", real_key, "\nreal_plaintext:", plaintext)
测试
加密
root@xxx # python3 Caesar_make.py
请输入密钥(0~25之间的整数): 3
请输入要加密的明文: Love what you do, Follow your heart.
您输入的key为: 3
您输入的明文是: Love what you do, Follow your heart.
变化后的密文是: Ilsb texq vlr al, Cliilt vlro ebxoq.
可见程序正确的将明文进行了加密,区分出大小写字母以及其他符号。
解密
root@xxx # python3 Caesar_solve.py
请输入要解密的密文: Ilsb texq vlr al, Cliilt vlro ebxoq.
key: 0 accuracy: 0 plaintext: Ilsb texq vlr al Cliilt vlro ebxoq
key: 1 accuracy: 0 plaintext: Jmtc ufyr wms bm Dmjjmu wmsp fcypr
key: 2 accuracy: 0 plaintext: Knud vgzs xnt cn Enkknv xntq gdzqs
key: 3 accuracy: 7 plaintext: Love what you do Follow your heart
key: 4 accuracy: 0 plaintext: Mpwf xibu zpv ep Gpmmpx zpvs ifbsu
key: 5 accuracy: 0 plaintext: Nqxg yjcv aqw fq Hqnnqy aqwt jgctv
key: 6 accuracy: 1 plaintext: Oryh zkdw brx gr Iroorz brxu khduw
key: 7 accuracy: 0 plaintext: Pszi alex csy hs Jsppsa csyv lievx
key: 8 accuracy: 1 plaintext: Qtaj bmfy dtz it Ktqqtb dtzw mjfwy
key: 9 accuracy: 0 plaintext: Rubk cngz eua ju Lurruc euax nkgxz
key: 10 accuracy: 0 plaintext: Svcl doha fvb kv Mvssvd fvby olhya
key: 11 accuracy: 0 plaintext: Twdm epib gwc lw Nwttwe gwcz pmizb
key: 12 accuracy: 0 plaintext: Uxen fqjc hxd mx Oxuuxf hxda qnjac
key: 13 accuracy: 0 plaintext: Vyfo grkd iye ny Pyvvyg iyeb rokbd
key: 14 accuracy: 1 plaintext: Wzgp hsle jzf oz Qzwwzh jzfc splce
key: 15 accuracy: 1 plaintext: Xahq itmf kag pa Raxxai kagd tqmdf
key: 16 accuracy: 0 plaintext: Ybir jung lbh qb Sbyybj lbhe urneg
key: 17 accuracy: 0 plaintext: Zcjs kvoh mci rc Tczzck mcif vsofh
key: 18 accuracy: 0 plaintext: Adkt lwpi ndj sd Udaadl ndjg wtpgi
key: 19 accuracy: 0 plaintext: Belu mxqj oek te Vebbem oekh xuqhj
key: 20 accuracy: 0 plaintext: Cfmv nyrk pfl uf Wfccfn pfli yvrik
key: 21 accuracy: 0 plaintext: Dgnw ozsl qgm vg Xgddgo qgmj zwsjl
key: 22 accuracy: 0 plaintext: Ehox patm rhn wh Yheehp rhnk axtkm
key: 23 accuracy: 1 plaintext: Fipy qbun sio xi Ziffiq siol byuln
key: 24 accuracy: 0 plaintext: Gjqz rcvo tjp yj Ajggjr tjpm czvmo
key: 25 accuracy: 0 plaintext: Hkra sdwp ukq zk Bkhhks ukqn dawnp
key: 3
real_plaintext: Love what you do Follow your heart
可见程序正确进行了解密,获得的密钥与明文与真实情况相同。