LAB2题解
-
关于仿射密码:移位密码和仿射密码的组合
k1, k2为参数,其中 ( k 1 , 26 ) = 1 (k1,~26)=1 (k1, 26)=1
加密变换: c = k 1 ∗ m + k 2 ( m o d 26 ) c=k1*m+k2~(mod~26) c=k1∗m+k2 (mod 26)
解密变换: m = i n v m o d ( k 1 , 26 ) ∗ ( c − k 2 ) ( m o d 26 ) m=invmod(k1,~26)*(c-k2)~(mod~26) m=invmod(k1, 26)∗(c−k2) (mod 26) ,invmod为求解逆元的库函数
k1与26互素的条件使得密钥空间大小为 k ∗ 26 = 12 ∗ 26 = 312 k*26 = 12*26 = 312 k∗26=12∗26=312def affine_decrypt(cpr): """ 仿射密码解密变换+暴力遍历 返回所有解密结果的列表 """ msg = '' msg_lst = [] # 用于存储所有解密结果 for k in range(1, 26): # 需要互素 if k % 2 != 0 and k % 13 != 0: for b in range(0, 26): #。解密变换部分如下 for c in cpr: if 'a' <= c <= 'z': msg += chr((invmod(k, 26) * (ord(c) - ord('a') - b) % 26) + ord('a')) elif 'A' <= c <= 'Z': msg += chr((invmod(k, 26) * (ord(c) - ord('A') - b) % 26) + ord('A')) else: msg += c # 记录在列表里 msg_lst.append(msg) msg = "" else: continue return msg_lst
-
关于flag1的解密
c 1 = k 1 ∗ m + b 1 ( m o d 26 ) c 2 = k 2 ∗ c 1 + b 2 ( m o d 26 ) . . . c n = k n ∗ c n − 1 + b n ( m o d 26 ) 可以推出 : c 2 = { k 2 ∗ [ ( k 1 ∗ m + b 1 ) % 26 ] + b 2 } % 26 = k 1 ∗ k 2 ∗ m + ( k 2 ∗ b 1 + b 2 ) ( m o d 26 ) = k ∗ m + b ( m o d 26 ) c_1=k_1*m+b_1~(mod~26)\\ c_2=k_2*c_1+b_2~(mod~26)\\ ...\\ c_n=k_n*c_{n-1}+b_n(mod~26)\\ 可以推出:\\ c_2=\{k_2*[(k_1*m+b_1)~\%~26]+b_2\}~\%~26\\ ~~= k1*k2*m + (k2*b1+b2) (mod~26)\\ = k*m + b (mod~26)\\ c1=k1∗m+b1 (mod 26)c2=k2∗c1+b2 (mod 26)...cn=kn∗cn−1+bn(mod 26)可以推出:c2={k2∗[(k1∗m+b1) % 26]+b2} % 26 =k1∗k2∗m+(k2∗b1+b2)(mod 26)=k∗m+b(mod 26)
c
n
c_n
cn同理,所以无论加密几次,
c
n
c_n
cn的形式均满足仿射加密
c
=
k
1
∗
m
+
k
2
(
m
o
d
26
)
c=k1*m+k2~(mod~26)
c=k1∗m+k2 (mod 26)
即只需要使用遍历的方法解密一次即可
cipher1111 = n2s(37200174337018397991699782489711793459920274981156200)
# print(cipher1111) # cmdey{gAo_chu_c_e4sduh
lst_f = affine_decrypt(cipher1111)
for f in lst_f:
# 解密结果列表中找到aitmc开头的即为flag1
if f.startswith("aitmc"):
msg1 = f
# msg1 = "aitmc{yOu_are_a_m4ster"
-
关于flag2的解密
-
可以注意到flag2加密时并不满足仿射密码 ( k 1 , 26 ) = 1 (k_1,~26)=1 (k1, 26)=1 的条件
-
k 1 k_1 k1与26不互素时,原变换不成立,可采用差分办法:
c 2 = ( 2 m + 5 ) % 26 c 3 = ( 13 m + 5 ) % 26 c_2 = (2m+5)~\%~26\\ c_3 = (13m+5)~\%~26 c2=(2m+5) % 26c3=(13m+5) % 26
两式相减得到: c = c 3 − c 2 = 11 m % 26 c = c_3-c_2 = 11m~\%~26 c=c3−c2=11m % 26可以发现此变换为乘数密码,求解即可
-
-
乘数密码解密变换实现如下:
def multiplicative_decrypt(cpr2, cpr3): msg2 = "" for i in range(len(cpr2)): if "a" <= cpr2[i] <= "z": msg2 += chr(invmod(11, 26) * (ord(cpr3[i]) - ord(cpr2[i])) % 26 + ord('a')) else: msg2 += cpr2[i] return msg2
-
对flag2的解密与完整flag的拼接
cipher2 = n2s(8292150086010872004878152910041646326050429) # _0p_fpp1fn_jvjt3n} cipher3 = n2s(8292154073695097972629587067692076229686141) # _0s_fss1sf_ffss3s} messasge = msg1 + multiplicative_decrypt(cipher2, cipher3) print(messasge)
-