公式以下: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