Python密码学编程

会持续完善并增加注释

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.|

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值