古典密码
单表替代密码
构造一个密文字母表(下面讲的例子都以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=49%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)
本文深入探讨古典密码学中的单表替代密码,包括加法密码、乘法密码及仿射密码,解析加密与解密过程,揭示数学原理,如模运算、逆元计算等。

2790

被折叠的 条评论
为什么被折叠?



