BUAA^AITMCLAB&Lab2题解

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=k1m+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)(ck2) (mod 26) ,invmod为求解逆元的库函数
    ​ k1与26互素的条件使得密钥空间大小为 k ∗ 26 = 12 ∗ 26 = 312 k*26 = 12*26 = 312 k26=1226=312

    • 解密变换实现:暴力遍历所有可能的k1和k2进行解密

    def 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的解密

    • 可以注意到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=k1m+b1 (mod 26)c2=k2c1+b2 (mod 26)...cn=kncn1+bn(mod 26)可以推出:c2={k2[(k1m+b1) % 26]+b2} % 26  =k1k2m+(k2b1+b2)(mod 26)=km+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=k1m+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=c3c2=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)
      
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值