会持续完善并增加注释
5 凯撒密码的加解密:
# -*- coding: UTF-8 -*-
# 凯撒密码程序的源代码
# 凯撒密码的密钥范围是0~25的整数
#要加/解密的字符串
message='This is my secret message.'
#加/解密的密钥
key=13
#程序是加密还是解密
mode='encrypt' #设置为encrypt或decrypt
#加密所使用的符号
SYMBOLS='ABCDEDGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?.'
#存储消息的加/解密形式
translated=''
for symbol in message:
#注意:只能加/解密SYMBOLS字符串中的符号
if symbol in SYMBOLS:
symbolIndex=SYMBOLS.find(symbol)
#执行加/解密
if mode=='encrypt':
translatedIndex=symbolIndex+key
elif mode=='decrypt':
translatedIndex=symbolIndex-key
#如果加密信息太长,则需要回环
if translatedIndex>=len(SYMBOLS):
translatedIndex=translatedIndex-len(SYMBOLS)
elif translatedIndex<0:
translatedIndex=translatedIndex+len(SYMBOLS)
translated=translated+SYMBOLS[translatedIndex]
else:
#添加未加/解密的字符
translated=translated+symbol
print(translated)
运行结果:
guv6Jv6Jz!J6rp5r7Jzr66ntrM
6 暴力破解凯撒密码
# -*- coding: UTF-8 -*-
# 暴力破解凯撒密码程序的源代码
# 凯撒密码的密钥范围是0~25的整数
#要解密的字符串
message='guv6Jv6Jz!J6rp5r7Jzr66ntrM'
#加密所使用的符号
SYMBOLS='ABCDEDGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?.'
for key in range(len(SYMBOLS)):
# 将translated设置未空字符很重要,这样可以清楚上一个迭代中translated的值
#存储消息的加/解密形式
translated=''
#程序的其余部分与凯撒加解密程序几乎相同
#循环遍历message中每一个字符
for symbol in message:
if symbol in SYMBOLS:
symbolIndex=SYMBOLS.find(symbol)
translatedIndex=symbolIndex-key
#执行回环
if translatedIndex<0:
translatedIndex=translatedIndex+len(SYMBOLS)
#添加解密的字符
translated=translated+SYMBOLS[translatedIndex]
else:
#添加未加/解密的字符
translated=translated+symbol
#显示每一个可能的解密值
print('Key #%s: %s' % (key,translated))
输出结果:
Key #0: guv6Jv6Jz!J6rp5r7Jzr66ntrM
Key #1: ftu5Iu5Iy I5qo4q6Iyq55msqL
Key #2: est4Ht4Hx0H4pn3p5Hxp44lrpK
Key #3: drs3Gs3Gw9G3om2o4Gwo33kqoJ
Key #4: cqr2Dr2Dv8D2nl1n3Dvn22jpnI
Key #5: bpq1Eq1Eu7E1mkzm2Eum11iomH
Key #6: aopzDpzDt6Dzljyl1DtlzzhnlG
Key #7: ZnoyCoyCs5CykixkzCskyygmkD
Key #8: YmnxBnxBr4BxjhwjyBrjxxfljE
Key #9: XlmwAmwAq3AwigvixAqiwwekiD
Key #10: Wklv.lv.p2.vhfuhw.phvvdjhC
Key #11: Vjku?ku?o1?ugetgv?oguucigB
Key #12: Uijt!jt!nz!tfdsfu!nfttbhfA
Key #13: This is my secret message.
Key #14: Sghr0hr0lx0rdbqds0ldrrZfd?
Key #15: Rfgq9gq9kw9qcapcr9kcqqYec!
Key #16: Qefp8fp8jv8pbZobq8jbppXdb
Key #17: Pdeo7eo7iu7oaYnap7iaooWca0
Key #18: Ocdn6dn6ht6nZXmZo6hZnnVbZ9
Key #19: Nbcm5cm5gs5mYWlYn5gYmmUaY8
Key #20: Mabl4bl4fr4lXVkXm4fXllTZX7
Key #21: LZak3ak3eq3kWUjWl3eWkkSYW6
Key #22: KYZj2Zj2dp2jVTiVk2dVjjRXV5
Key #23: JXYi1Yi1co1iUShUj1cUiiQWU4
Key #24: IWXhzXhzbnzhTRgTizbThhPVT3
Key #25: HVWgyWgyamygSQfShyaSggOUS2
Key #26: GUVfxVfxZlxfRPeRgxZRffNTR1
Key #27: DTUewUewYkweQOdQfwYQeeMSQz
Key #28: ESTdvTdvXjvdPNcPevXPddLRPy
Key #29: DRScuScuWiucOMbOduWOccKQOx
Key #30: CQRbtRbtVhtbNLaNctVNbbJPNw
Key #31: BPQasQasUgsaMKZMbsUMaaIOMv
Key #32: AOPZrPZrTfrZLJYLarTLZZHNLu
Key #33: .NOYqOYqSeqYKIXKZqSKYYGMKt
Key #34: ?MNXpNXpRdpXJHWJYpRJXXDLJs
Key #35: !LMWoMWoQcoWIGVIXoQIWWEKIr
Key #36: KLVnLVnPbnVHDUHWnPHVVDJHq
Key #37: 0JKUmKUmOamUGETGVmOGUUCIGp
Key #38: 9IJTlJTlNZlTDDSDUlNDTTBHDo
Key #39: 8HISkISkMYkSECRETkMESSAGEn
Key #40: 7GHRjHRjLXjRDBQDSjLDRR.DDm
Key #41: 6DGQiGQiKWiQCAPCRiKCQQ?ECl
Key #42: 5EDPhDPhJVhPB.OBQhJBPP!DBk
Key #43: 4DEOgEOgIUgOA?NAPgIAOO CAj
Key #44: 3CDNfDNfHTfN.!M.OfH.NN0B.i
Key #45: 2BCMeCMeGSeM? L?NeG?MM9A?h
Key #46: 1ABLdBLdDRdL!0K!MdD!LL8.!g
Key #47: z.AKcAKcEQcK 9J LcE KK7? f
Key #48: y?.Jb.JbDPbJ08I0KbD0JJ6!0e
Key #49: x!?Ia?IaCOaI97H9JaC9II5 9d
Key #50: w !HZ!HZBNZH86G8IZB8HH408c
Key #51: v0 GY GYAMYG75D7HYA7GG397b
Key #52: u90DX0DX.LXD64E6GX.6DD286a
Key #53: t89EW9EW?KWE53D5DW?5EE175Z
Key #54: s78DV8DV!JVD42C4EV!4DDz64Y
Key #55: r67CU7CU IUC31B3DU 3CCy53X
Key #56: q56BT6BT0HTB2zA2CT02BBx42W
Key #57: p45AS5AS9GSA1y.1BS91AAw31V
Key #58: o34.R4.R8DR.zx?zAR8z..v2zU
Key #59: n23?Q3?Q7EQ?yw!y.Q7y??u1yT
Key #60: m12!P2!P6DP!xv x?P6x!!tzxS
Key #61: lz1 O1 O5CO wu0w!O5w sywR
Key #62: kyz0Nz0N4BN0vt9v N4v00rxvQ
Key #63: jxy9My9M3AM9us8u0M3u99qwuP
Key #64: iwx8Lx8L2.L8tr7t9L2t88pvtO
Key #65: hvw7Kw7K1?K7sq6s8K1s77ousN
显然在66种解密信息中,只有第13中可能Key #13: This is my secret message.存储了正常信息,因此key=13
7 柱状 置换密码加密
'Common sense is not so common.'这条消息共30个字符(包括空格和标点符号)。将密钥取8进行加密。
柱状密码类型,密钥的可能范围是从2到消息的一半,该示例的取值范围是2~15,此处密钥取8进行加密。这种加密方式,信息越长,可能的密钥越多。
- step 1:画连续8个框以匹配密钥的数值
- step2:将要加密的消息写入框中,在每个框中放置一个字符(包括空格和标点符号)。
一行填满之后,则另起一行填写,指至整个消息都填入。
加密方式:将明文根据密钥写成行的形式,加密的时候字符以列的形式读取。
因此,在程序实现加密时,可以根据字符对应的索引位置进行加密。
明文排列时的索引:
C 0 | o 1 | m 2 | m 3 | o 4 | n 5 | - 6 | s 7 |
---|---|---|---|---|---|---|---|
e 8 | o 9 | s 10 | e 11 | - 12 | i 13 | s 14 | - 15 |
n 16 | o 17 | t 18 | - 19 | s 20 | o 21 | - 22 | c 23 |
o 24 | m 25 | m 26 | o 27 | n 28 | . 29 | * | * |
加密时的索引,
C 0+0=0 | o 1+0=1 | m 2+0=2 | m 3+0=3 | o 4+0=4 | n 5+0=5 | - 6+0=6 | s 7+0=7 |
---|---|---|---|---|---|---|---|
e 0+8=8 | o 1+8=9 | s 2+8=10 | e 3+8=11 | - 4+8=12 | i 5+8=13 | s 6+8=14 | - 7+8=15 |
n 0+16=16 | o 1+16=17 | t 2+16=18 | - 3+16=19 | s 4+16=20 | o 5+16=21 | - 6+16=22 | c 7+16=23 |
o 0+24=24 | m 1+24=25 | m 2+24=26 | o 3+24=27 | n 4+24=28 | . 5+24=29 | * | * |
注:表格中“-”表示空格,*表示无符号,即忽略。
代码一:业余实现(不专业)
# -*- coding: UTF-8 -*-
#柱状置换密码
#密钥取8
def encryption(message,key):
ciphertext=''
if len(message) % key>0:
row=int(len(message) / key +1)
else:
row=int(len(message) / key)
column=key
for i in range(column):
for j in range(row):
if i+j*8<30:
ciphertext +=message[i+j*8]
print(ciphertext)
if __name__=='__main__':
message='Common sense is not so common.'
key=8
encryption(message, key)
运行结果:
Cenoonommstmme oo snnio. s s c
代码二:
加密源代码:(还是官方给出的代码比较完善~)
# -*- coding: UTF-8 -*-
#柱状置换密码
#密钥取8
def main():
myMessage='Common sense is not so common.'
myKey=8
ciphertext=encryptMessage(myKey,myMessage)
#将密文字符串打印到屏幕上,并添加“|”(管道字符),以防加密信息末尾有空格
print(ciphertext+"|")
def encryptMessage(key,message):
#密文中的每个字符串表示列表中的一列
ciphertext=['']*key
#循环遍历密文中的每一列
for column in range(key):
currentIndex=column
#继续循环,指导currentIndex超过message的长度
while currentIndex<len(message):
#将message中的currentIndex字符放在密文列表中
#当前列的末尾
ciphertext[column] +=message[currentIndex]
#改变currentIndex
currentIndex +=key
#将密文列表转换为单个字符串值并返回
return "".join(ciphertext)
if __name__=='__main__':
main()
运行结果:
Cenoonommstmme oo snnio. s s c|
8 柱状置换密码解密
解密柱状置换密码的步骤:
- 用密文长度除以密钥长度,并将所得结果向上取整
- 画出转换表的行和列。列数为步骤1中得到的整数,行数为密钥
- 用网格总数减去密文长度,计算出需要空出的网格总数
- 根据步骤3的计算结果,将最右侧一列底部相应数目的网格做出空白标记“*”
- 从最左侧一列凯撒,从上至下阅读字符,对每一列依次进行相同的操作,得到明文。
C 0+0=0 | e 1+0=1 | n 2+0=2 | o 3+0=3 |
---|---|---|---|
o 0+4=4 | n 1+4=5 | o 2+4=6 | m 3+4=7 |
m 0+8=8 | s 1+8=9 | t 2+8=10 | m 3+8=11 |
m 0+12=12 | e 5+8=13 | - 6+8=14 | o 7+8=15 |
o 0+16=16 | - 1+16=17 | s 2+16=18 | n 3+16=19 |
n 0+20=20 | i 5+16=21 | o 6+16=22 | . 7+16=23 |
- 0+24=24 | s 1+24=25 | - 2+24=26 | * 3+24=27 |
s 0+28=28 | - 5+24=29 | c 2+28=30 | * 3+28=31 |
代码一:
# -*- coding: utf-8 -*-
def decrypt(ciphertext,key):
column=int(len(ciphertext) / key)+1
row=key
space=row*column-len(ciphertext)
temp=list(ciphertext) #将字符型转换为列表,然后将排列后的空白部分使用“*”符号补充完整
for i in range(space,0,-1):
temp.insert(4*(row-i)+column-1,'*') #将排列后的空白部分使用“*”符号补充完整
ciphertext=''.join(temp)
plaintext=''
#简洁形式:
for i in range(column):
for j in range(row):
if ciphertext[i+j*4]!='*':
plaintext +=ciphertext[i+j*4]
print(plaintext)
"""
for i in range(column-1):
for j in range(row):
#如果字符为“*”时,则跳过,其实此处可以省略这条语句,
#因为我将前3列和最后一列分开读取了,并且不会读取“*”的位置,只需要将空白部分用某个字符填充就可以
#这个部分可以写的更简洁
#if ciphertext[i+j*4] !='*':
plaintext +=ciphertext[i+j*4]
i=column-1
for j in range(row-space):
#if ciphertext[i+j*4]!='*':
plaintext +=ciphertext[i+j*4]
print(plaintext)
"""
if __name__=='__main__':
key=8
ciphertext='Cenoonommstmme oo snnio. s s c'
decrypt(ciphertext, key)
#'Common sense is not so common.'
运行结果:
Common sense is not so common.
代码二~源码:
# -*- coding: utf-8 -*-
#置换密码解密
import math
def main():
myMessage='Cenoonommstmme oo snnio. s s c'
myKey=8
plaintext=decryptMessage(myKey,myMessage)
#打印 | (管道字符)以防在解密消息末尾有空格
print(plaintext+"|")
def decryptMessage(key,message):
#置换密码解密函数将通过字符串列表来模拟
#明文转换表的列和行
#首先,需要计算一些值
#转换表中列的数目
numOfColumns=int(math.ceil(len(message) / float(key)))
#转换表中行的数目
numOfRows=key
#转换表最后一列中的阴影数量
numOfShadedBoxes=(numOfColumns*numOfRows)-len(message)
#明文中每个字符串表示一列
plaintext=['']*numOfColumns
#列和行变量指向加密消息中下一个字符在表中的位置
column=0
row=0
for symbol in message:
plaintext[column]+=symbol
column+=1 #指向下一列
#如果没有更多的列或者阴影中,则回到第1列的下一行
if (column==numOfColumns) or (column==numOfColumns-1 and row>=numOfRows-numOfShadedBoxes):
column=0
row+=1
return ''.join(plaintext)
if __name__=='__main__':
main()
运行结果:
Common sense is not so common.|