密碼學與python的那些事

密碼學與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庫code

"""
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)

求逆元使用手寫代碼:blog

"""
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
相關文章
相關標籤/搜索