密码学笔记——简单密码Python实现

本文深入探讨古典密码学中的单表替代密码,包括加法密码、乘法密码及仿射密码,解析加密与解密过程,揭示数学原理,如模运算、逆元计算等。

古典密码

单表替代密码

构造一个密文字母表(下面讲的例子都以26个字母的字母表为例),用密文字母表中的字母或者字母组来代替明文字母或字母组,各字母组或字母组的相对位置不变,但其本身的值改变了。
将26个字母与十进制数字中的0~25相对应,数的加法和乘法都定义为模26的加法和乘法。

1. 加法密码

模p的加法:
a%p(或a(mod p))表示a除以p的余数。
例k=3,3%26=3,y=x+3(mod26)此时就是非常熟悉的凯撒密码。

明文:ABCDEFGHIJKLMNOPQRSTUVWXYZ
位置:0123456789……………………………25
密文:DEFGHIJKLMNOPQRSTUVWXYZABC

当k=3时实际上就是所有数往前移了3位,最开始三位则是按顺序挪到后面。
加密:y=x+k(mod26)
当x=1(位置为1,明文中是B),加密后y=1+3(mod26)=1+3=4。
即1的位置被原来4位置上的值(E)所占据了。
解密:x=y-k(mod26)
当y=4,x=4-3(mod26)=1

flag='asfjkhjf'
k=8
#加法密码:y=x+k(mod26)
table=[]
for i in flag:
    table.append(ord(i)-97)
flag=""
for j in table:
    flag+=chr((j-8)%26+97)
print(flag)
2. 乘法密码

加密:y=kx(mod26)
解密函数要求密钥k在mod26下有乘法逆元,有乘法逆元代表k与26互素
与26互素的数:1,3,5,7,9,11,15,17,19,21,23,25.共12个,可供选择范围很有限。
解密:x=k-1y(mod26)
关键在于计算k-1:运用扩展的欧几里得算法求k在mod26下的逆。

计算e对于φ(n)的模反元素d,所谓"模反元素"就是指有一个整数d,可以使得ed被φ(n)除的余数为1。
若(m,n)=1,则存在整数k1,k2使得k1m+k2n=1,这里的k1就是m-1mod n.

设k=9

明文:ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文:AJSBKTCLUDMVENWFOXGPYHQZIR

加密:
x=0,y=0*9%26=0,(*/%是运算优先等级同级,计算时按从左到右来)因此最开始的位置还是被编号为0的字母A占据
x=13,y=139%26=117%26=13.即13号位置(明文中的N)还是被编号为13的字母N占据
x=4,y=4
9%26=10。即明文中的4号位最终被编号为10的K占据。
解密:
先求9关于模26的逆

笔算:
26=9*2+8
9=8*1+1
8=1*8
将商数逆序排列(a1,a0)
1 2
b-1=1,b0=an,bi=an-i*bi-1+bi-2
如果n为奇数,则bn为所求逆元
如果n为偶数,则N(模数)-bn为所求逆元
这里b1=3为9mod26的逆元。

这是按照笔算的步骤写的,按原理求逆,实际计算机计算逆只要一个循环进行匹配就好了,不必这么麻烦。
#求a关于mod b的逆
def modinverse(a,b):
    N=b
    s=[0]*10
    i=9
    while a!=0:
        s[i]=b//a
        a , b = b%a , a
        i=i-1
    s=s[i+2:]
    t=[]
    x=0
    t.extend([1,s[0]])#用extend可以一次添加多个元素
    for j in range(2,len(s)+1):
        x=t[j-1]*s[j-1]+t[j-2]
        t.append(x)
    if len(t)%2==0:
        print(N-t[-1])
    else:
        print(t[-1])
    return

得出逆为3后就可以由公式得结果了。

def crypmulti(miwen,k):
    str=""
    for i in range(len(miwen)):
        k1=modinverse(k,26)#求k的逆
        j=k1*i%(26)
        str+=miwen[j]
    return str
简单版本
flag="djkhghskhgkjws"
k=9
#乘法密码:y=kx(mod26)
table=[]
for i in flag:
    table.append(ord(i)-97)
cry=""
for j in table:
    for i in range(26):
        if i*k%26==j:#简化版,不用求逆了,直接匹配除了最终结果
            cry+=chr(i+97)
print(cry)

##### 3. 仿射密码
将乘法和加法相结合
加密:y=kx+b(mod26)
密钥:k,b
解密:x=k^-1^(y-b)(mod26)
条件:(k,26)=1

```python
flag="djkhghskhgkjws"
k=9
#乘法密码:y=kx(mod26)
table=[]
for i in flag:
    table.append(ord(i)-97)
cry=""
for j in table:
    for i in range(26):
        if i*k%26==j:
            cry+=chr(i+97)
print(cry)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值