引例: 1.3 三階矩陣希爾加密
1.3. 計算定義在Zg上矩陣K=((1 11 12),(4 23 2),(17 15 9))的逆K-1,並用K作為希爾密碼體制的密鑰完成對
明文串: looking forward to our national day 的加密和相應密文串的解密.1.3 答案說明:逆矩陣是對的,但是密文串與答案不符。原因是輸入矩陣時,按行輸入和按列輸入的差異。如下提供兩種python求解方式
代碼結果:按行輸入舉證,密文串密文:VEDUQRVLRZCVSTLSCEEDQPCXPWIFIH
代碼結果:按列輸入舉證,密文串密文:TDADVTEBABROOVRUWMRSWDFGSWVVDS -- 這是答案中的
代碼一:自定義階數求解
import numpy as np
import math
from sympy import Matrix
# decryption function
def decrypt(key_matrix_inv, cipher_text,dimensions):
"""
Arguments: key matrix inverse, cipher text
Returns: plain text
"""
print("Matrix Inverse is: \n", key_matrix_inv)
cipher_len = len(cipher_text)
# create cipher text matrix (ASCII Values - 65 to get from 0 to X)
cipher_text_matrix = []
addLen=0
plain_text=""
#print("cipher_text",cipher_text)
if cipher_len % dimensions != 0:
addLen = dimensions - cipher_len % dimensions
for i in range(int((cipher_len+addLen)/dimensions)):
result = []
cipher_text_matrix=[]
for j in range(dimensions):
# print(i," ",j)
cipher_text_matrix.append(cipher_text[i*dimensions+j]-65)
cipher_text_matrix = np.array(cipher_text_matrix)
#print("Cipher Key Matrix",i,":\n", cipher_text_matrix)
# multiply inverse with cipher text matrix
result = np.array(np.dot(key_matrix_inv, cipher_text_matrix))
#print("Decrypted Matrix\n", result)
# convert result matrix to plain text by using chr()
for t in range(dimensions):
plain_text += chr(result[t] % 26 + 65)
return plain_text
'''
# multiply inverse with cipher text matrix
result = np.array(np.dot(key_matrix_inv, cipher_text_matrix))
# BUG
# print(result[0][1], int(result[0][1]))
print("Decrypted Matrix\n", result)
# create empty string for plain text
plain_text = ""
# convert result matrix to plain text by using chr()
for i in range(dimensions):
plain_text += chr(int(round(result[0][i], 0) % 26 + 65))
# return the decrypted plain text
return plain_text
'''
if __name__ == "__main__":
# take input from the user
plain_text = str(input("Plain Text: ")).upper()
# dimensions of the matrix = length(plain text) x length(plain text)
dimensions = int(input("Dimensions:"))
cipher_len = len(plain_text.lower())
# plain text matrix
plain_text_matrix = []
# creating a column matrix for plain text characters
for i in range(cipher_len):
plain_text_matrix.append(ord(plain_text[i]))
plain_text_matrix = np.array(plain_text_matrix)
print("Plain Text Matrix\n", plain_text_matrix)
print("Enter values for the key: ")
# take values for the key matrix
key_matrix = []
for i in range(dimensions):
row_ = []
for j in range(dimensions):
value = int(input(str(i) + ", " + str(j) + " value: "))
row_.append(value)
key_matrix.append(row_)
print("Key Matrix: \n")
# for encryption
key_matrix = np.array(key_matrix)
# for decryption
#key_matrix_inv = (np.linalg.inv(np.matrix(key_matrix)) % 26)
#key_matrix_inv = multi_inverse(np.linalg.det(key_matrix), 26) * \
# np.matrix(key_matrix).getH()
#print(np.matrix(key_matrix).getH())
# calculate key matrix inverse using modulo multiplicative inverse
#5-=21
#17=23
key_matrix=Matrix(key_matrix)
key_matrix_inv = key_matrix.inv_mod(26)
print("key_matrix_inv",key_matrix_inv)
key_matrix_inv= np.array(key_matrix_inv)
matrix_result = np.matmul(key_matrix_inv,key_matrix) % 26
#print("Result Matrix: \n", matrix_result)
#print("Inverse Key Matrix: \n", key_matrix_inv)
cipher_text=decrypt(key_matrix,plain_text_matrix,dimensions)
print("cipher_text: \n", cipher_text.upper())
print("cipher_len:",cipher_len)
cipher_text_matrix=[]
for i in range(cipher_len):
cipher_text_matrix.append(ord(cipher_text[i]))
cipher_text_matrix = np.array(cipher_text_matrix)
decrypted_plain_text=decrypt(key_matrix_inv,cipher_text_matrix,dimensions)
print("decrypted_plain_text: \n", decrypted_plain_text.lower())
## 注意輸入文本不含空格
# Plain Text: lookingforwardtoournationalday
# Dimensions:3
# Plain Text Matrix
# [76 79 79 75 73 78 71 70 79 82 87 65 82 68 84 79 79 85 82 78 65 84 73 79
# 78 65 76 68 65 89]
# Enter values for the key:
# 0, 0 value: 1
# 0, 1 value: 11
# 0, 2 value: 12
# 1, 0 value: 4
# 1, 1 value: 23
# 1, 2 value: 2
# 2, 0 value: 17
# 2, 1 value: 15
# 2, 2 value: 9
# Key Matrix:
# key_matrix_inv Matrix([[25, 11, 22], [10, 13, 4], [17, 24, 1]])
# Matrix Inverse is:
# Matrix([[1, 11, 12], [4, 23, 2], [17, 15, 9]])
# cipher_text:
# VEDUQRVLRZCVSTLSCEEDQPCXPWIFIH
# cipher_len: 30
# Matrix Inverse is:
# [[25 11 22]
# [10 13 4]
# [17 24 1]]
# decrypted_plain_text:
# lookingforwardtoournationalday
代碼二:指定階數求解
import numpy as np
def encode(string, size):
# 轉換小寫字母
if not string.islower():
string = string.lower()
# 分成 size個 字的分段
blocks = [string[i:i+size] for i in range(0, len(string), size)]
# 明文字串與密鑰矩陣階數不整除。。字串補a
if len(blocks[-1]) != size:
blocks[-1] = blocks[-1].ljust(size,'a')
# 將 a-z 編碼為 0-25
temp = np.array([list(map(ord, block)) for block in blocks]) - ord('a')
# print(temp)
return temp
def analysis(crypter, code):
return ((crypter @ code.T) % 26).T + ord('a')
# 要加密的信息
encode_msg = 'lookingforwardtoournationalday'.lower()
print('待加密的信息:'+encode_msg)
# 密鑰
encryption_matrix = np.array([[1,11,12], [4, 23,2],[17, 15,9]])
print('密鑰:')
print(encryption_matrix)
# 加密代碼
encrypted_code = analysis(encryption_matrix, encode(encode_msg, 3))
# 密文
Decryption_matrixtext = ''.join(map(chr, encrypted_code.ravel()))
print("密文:" + Decryption_matrixtext[:len(encode_msg)].upper())
# 待加密的信息:lookingforwardtoournationalday
# 密鑰:
# [[ 1 11 12]
# [ 4 23 2]
# [17 15 9]]
# 密文:VEDUQRVLRZCVSTLSCEEDQPCXPWIFIH