zoukankan      html  css  js  c++  java
  • 密码学与python的那些事

    密码学与python的那些事

    仿射变换

    公式如下:

    在这里插入图片描述

    加密

    """
    c代表密文,m代表明文,a, b表示密钥
    c = a*m + b (mod 26)
    m = a的逆元*(c-b) (mod 26)
    """
    m = "security".lower()
    c = ""
    a = 7
    b = 21
    for i in range(0, len(m)):
        c = c + chr((((ord(m[i])-97)*a+b)%26)+97)
    print(c)
    

    解密

    求逆元可以使用libnum库,也可以使用gmpy2库,也可以手写代码。

    求逆元使用libnum库:

    """
    c代表密文,m代表明文,a, b表示密钥
    c = a*m + b (mod 26)
    m = a的逆元*(c-b) (mod 26)
    d表示a的逆元
    """
    import libnum
    
    
    c = "vlxijh".lower()
    m = ""
    a = 7
    b = 21
    d = libnum.xgcd(a, 26)[0]
    for i in range(0, len(c)):
        m = m + chr((((ord(c[i])-97)-b+26)*d)%26 + 97)
    print(m)
    

    求逆元使用gmpy2库

    """
    c代表密文,m代表明文,a, b表示密钥
    c = a*m + b (mod 26)
    m = a的逆元*(c-b) (mod 26)
    d表示a的逆元
    """
    import gmpy2
    
    
    c = "vlxijh".lower()
    m = ""
    a = 7
    b = 21
    d = gmpy2.invert(a, 26)
    print(d)
    for i in range(0, len(c)):
        m = m + chr((((ord(c[i])-97)-b+26)*d)%26 + 97)
    print(m)
    

    求逆元使用手写代码:

    """
    c代表密文,m代表明文,a, b表示密钥
    c = a*m + b (mod 26)
    m = a的逆元*(c-b) (mod 26)
    d表示a的逆元
    """
    
    
    def egcd(a, b):
        if (b == 0):
            return 1, 0, a
        else:
            x, y, q = egcd(b, a % b)  # q = GCD(a, b) = GCD(b, a%b)
            x, y = y, (x - (a // b) * y)
            return x, y, q
    
    
    def mod_inv(a, b):
        return egcd(a, b)[0] % b  # 求a模b得逆元
    
    
    c = "vlxijh".lower()
    m = ""
    a = 7
    b = 21
    d = mod_inv(a, 26)
    for i in range(0, len(c)):
        m = m + chr((((ord(c[i])-97)-b+26)*d)%26 + 97)
    print(m)
    

    多表代换密码

    加密:

    import numpy as np
    
    
    q = input("输入矩阵A:(格式为:[[11, 2, 19], [5, 23, 25], [20, 7, 17]]):")
    a = np.mat(eval(q))
    w = input("输入矩阵B:")
    # 将矩阵B转置
    b = np.mat(eval(w)).T
    # 原文与矩阵转换
    e = input("输入原文:")
    
    elist = list(e)
    for i in range(len(elist)):
        elist[i] = ord(elist[i]) - 97
    x = np.zeros((3, int(len(elist) / 3)), dtype=int)
    m = np.mat(x)
    
    i = 0
    h = 0
    for i in range(int(len(elist) / 3)):
        j = 0
        for j in range(3):
            m[j, int(h / 3)] = elist[h]
            h = h + 1
    # 提取矩阵的某一列
    # print(m[:, 0])
    # 加密算法
    c = m
    for i in range(0, int(len(elist) / 3)):
        c[:, i] = (np.dot(a, m[:, i]) + b) % 26
    
    # print(c)
    # 矩阵与密文转换
    i = 0
    h = 0
    print("加密结果")
    crypto = ""
    for i in range(int(len(elist) / 3)):
        j = 0
        for j in range(3):
            crypto = crypto + chr(c[j, int(h / 3)] + 97)
            # sys.stdout.write(chr(c[j, int(h / 3)] + 97))
            h = h + 1
    print(crypto)
    
    
    # [[11, 2, 19], [5, 23, 25], [20, 7, 17]]
    # [0,0,0]
    # yourpinnoisfouronetwosix
    

    解密:

    import numpy as np
    from numpy.linalg import *
    
    
    # 矩阵取摸
    def my_int_inv(mat, n=26):
        x = np.zeros(mat.shape, dtype=np.int16)
        for i in range(mat.shape[0]):
            for j in range(mat.shape[1]):
                x[i, j] = int(round(mat[i, j])) % n
        return x
    
    
    # 欧几里德算法
    def gcd(a, b):
        while a != 0:
            a, b = b % a, a
        return b
    
    
    # 扩展欧几里德算法
    def exgcd(a, m):
        if gcd(a, m) != 1:
            return None
        u1, u2, u3 = 1, 0, a
        v1, v2, v3 = 0, 1, m
        while v3 != 0:
            q = u3 // v3
            v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
        return u1 % m
    
    
    q = input("输入矩阵A:(格式为:[[11, 2, 19], [5, 23, 25], [20, 7, 17]]):")
    a = np.mat(eval(q))
    w = input("输入矩阵B:")
    # 将矩阵B转置
    b = np.mat(eval(w)).T
    # 密文与矩阵转换
    e = input("输入密文:")
    
    elist = list(e)
    for i in range(len(elist)):
        elist[i] = ord(elist[i]) - 97
    x = np.zeros((3, int(len(elist) / 3)), dtype=int)
    c = np.mat(x)
    
    
    i = 0
    h = 0
    for i in range(int(len(elist) / 3)):
        j = 0
        for j in range(3):
            c[j, int(h / 3)] = elist[h]
            h = h + 1
    
    # print(c)
    # 提取矩阵的某一列
    # print(m[:, 0])
    
    # 求a的逆元
    a_inv = a.I
    a_det = det(a)
    a_adju = my_int_inv(a_det * a_inv)
    a_det_inv = exgcd(int(round((det(a) % 26))), 26)
    aa_inv = my_int_inv(a_det_inv * a_adju)
    
    # 解密算法
    m = c
    for i in range(0, int(len(elist) / 3)):
        m[:, i] = (np.dot(aa_inv, c[:, i]) + b) % 26
    
    # print(c)
    
    
    
    
    
    # 矩阵与密文转换
    i = 0
    h = 0
    print("解密结果")
    plantext = ""
    for i in range(int(len(elist) / 3)):
        j = 0
        for j in range(3):
            plantext = plantext + chr(c[j, int(h / 3)] + 97)
            # sys.stdout.write(chr(c[j, int(h / 3)] + 97))
            h = h + 1
    print(plantext)
    
    
    # [[11, 2, 19], [5, 23, 25], [20, 7, 17]]
    # [0,0,0]
    # wgifgjtmrlhhxthwbxzpsbrb
    
  • 相关阅读:
    java将文件夹md5为名的图片与数据库查询对应md5后导入相应图片到某分类下
    java 导入图片时忘了导入诊断报告,查询报告并将缺失的报告插入对应分类图片中
    安装nginx
    python,opencv,8位图转24位图
    python 笔记
    python,opencv图像增强
    问卷星的使用教程
    考研数据结构复习随笔-基本概念(一)
    按字寻址 按字节寻址
    在数据结构中用顺序栈解决括号匹配问题
  • 原文地址:https://www.cnblogs.com/v01cano/p/11798433.html
Copyright © 2011-2022 走看看