hill密码c 语言程序,Hill密码的加密与解密(C语言)

题目描述

写一个程序实现2*2 Hill密码的加解密算法

遇到的问题

加密过程写的很顺利,因为是2*2矩阵,一些本应该用矩阵乘法计算的东西也直接被我简化成用算式表示了。

在写解密过程是遇到了问题,矩阵求逆的部分不太会做。跟着书上前面的例题看了一下。书上说对于2*2的矩阵,求其行列式。如果矩阵A有非零的行列式,则这个矩阵的逆如下计算:[A^(-1)]ij = (det A)^(-1) * (-1)^(i+j) * (Dij), 其中(Dij)是将矩阵去掉第j行和第i列后的子行列式的值,det(A)是A的行列式,而(det A)^(-1)是det(A) mod 26的逆。

然后举了个例子,矩阵A = 5 8 17 3; det A = (5 * 3) - (8 * 17) = -121 mod 26 = 9

因为9*3 = 27 mod 26 = 1,可得到9^(-1) mod 26 = 3

因此,A^(-1) mod 26 = 3 * (3, -8, -17, 5) = 3 * (3, 18, 9, 5) = (9, 54, 27, 15) = (9, 2, 1, 15)

啊对就这里。最开始我怎么都没看明白,后面去问别人人给我说就是对其中的每一个元素mod 26而已我才发现。wow这真是厉害极了。知道这个规律之后这也就好求逆了。

编写的代码如下

#include

#include

#include

#define MAX 60

int main()

{

int K1[2][2] = {0}, K2[2][2] = {0};

int Temp1[2] = {0}, Temp2[2] = {0};

char P[MAX] = {0}, C[MAX] = {0};

int T1[MAX] = {0}, T2[MAX] = {0};

int len, flag=0, temp, temp1, i, j, num=0;

printf("======= Hill 密码 =======\n\n");

printf("请输入秘钥的值:\n");

for(i=0; i<2; i++)

{

for(j=0; j<2; j++)

{

scanf("%d", &K1[i][j]);

}

}

printf("\n1. 加密\t 2. 解密\n请选择:");

scanf("%d", &num);

if(num == 1)

{

printf("请输入明文:\n");

scanf("%s", P);

len = strlen(P);

// 当长度为奇数时补齐一位

if(len % 2 == 1)

{

P[len] = 'a';

len = strlen(P);

flag = 1;

}

// 将大写转成小写,并赋值给T1数组

for(i=0; iif(P[i] >= 'A' && P[i] <= 'Z')

{

P[i] = P[i] + 32;

}

T1[i] = P[i] - 'a';

}

// 得到加密后结果,存储在T2中

for(i=0; i2)

{

Temp1[0] = T1[i];

Temp1[1] = T1[i + 1];

// Temp2存储密文int值

Temp2[0] = (Temp1[0] * K1[0][0] + Temp1[1] * K1[1][0]) % 26;

Temp2[1] = (Temp1[0] * K1[0][1] + Temp1[1] * K1[1][1]) % 26;

T2[i] = Temp2[0];

T2[i + 1] = Temp2[1];

}

if(flag == 1)

{

len = len - 1;

}

printf("加密结果为:\n");

for(i=0; i'a';

printf("%c ", C[i]);

}

printf("\n");

}

else if(num == 2)

{

printf("请输入密文:");

scanf("%s", C);

len = strlen(C);

// 当长度为奇数时补齐一位

if(len % 2 == 1)

{

C[len] = 'a';

len = strlen(C);

flag = 1;

}

for(i=0; iif(C[i] >= 'A' && C[i] <= 'Z')

{

C[i] = C[i] + 32;

}

T2[i] = C[i] - 'a';

}

// 求K的逆

temp = -1;

for(i=1; temp < 0; i++)

{

temp = (K1[0][0] * K1[1][1] - K1[0][1] * K1[1][0]) + 26 * i;

}

i = 1;

while(1)

{

if((temp * i) % 26 == 1)

{

temp1 = i;

break;

}

else

{

i++;

}

}

K2[0][0] = K1[1][1] * temp1;

K2[0][1] = (((-1 * K1[0][1]) + 26) * temp1) % 26;

K2[1][0] = (((-1 * K1[1][0]) + 26) * temp1) % 26;

K2[1][1] = K1[0][0] * temp1;

// printf(" %d %d %d %d %d %d\n",temp, temp1, K2[0][0], K2[0][1], K2[1][0], K2[1][1]);

// system("pause");

// printf(" %d %d %d %d %d %d\n",temp, temp1, K2[0][0]%26, K2[0][1]%26, K2[1][0]%26, K2[1][1]%26);

// system("pause");

// 得到解密后结果,存储在T2中

for(i=0; i2)

{

Temp2[0] = T2[i];

Temp2[1] = T2[i + 1];

// Temp1存储明文int值

Temp1[0] = (Temp2[0] * K2[0][0] + Temp2[1] * K2[1][0]) % 26;

Temp1[1] = (Temp2[0] * K2[0][1] + Temp2[1] * K2[1][1]) % 26;

T1[i] = Temp1[0];

T1[i + 1] = Temp1[1];

}

if(flag == 1)

{

len = len - 1;

}

printf("解密结果为:\n");

for(i=0; i'a';

printf("%c ", P[i]);

}

printf("\n");

}

else

{

printf("error!");

exit(0);

}

return 0;

}

附带测试数据:

输入数组: 9 4 5 7

明文: meetmeattheusualplaceatthenratherthaneightoclock

密文: yybtyyrdyvgacedzihkokqgbfeuprdfeotlchcywcfgsnmqa

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hill密码是一种基于线性代数的加密算法,可以用矩阵运算实现加密解密。下面是用Python实现Hill密码加密解密的示例代码: ```python import numpy as np # 加密函数 def hill_encrypt(plain_text, key): # 将明文转换为数字序列 plain_num = [ord(c) - ord('a') for c in plain_text.lower()] # 将数字序列转换为矩阵 plain_matrix = np.array(plain_num).reshape(-1, 1) # 将密钥转换为矩阵 key_matrix = np.array(key) # 计算加密后的矩阵 cipher_matrix = np.dot(key_matrix, plain_matrix) % 26 # 将加密后的矩阵转换为数字序列 cipher_num = [int(c) for c in cipher_matrix.reshape(1, -1)[0]] # 将数字序列转换为密文 cipher_text = ''.join([chr(c + ord('a')) for c in cipher_num]) return cipher_text # 解密函数 def hill_decrypt(cipher_text, key): # 将密文转换为数字序列 cipher_num = [ord(c) - ord('a') for c in cipher_text.lower()] # 将数字序列转换为矩阵 cipher_matrix = np.array(cipher_num).reshape(-1, 1) # 将密钥转换为矩阵 key_matrix = np.array(key) # 计算解密后的矩阵 inv_key_matrix = np.linalg.inv(key_matrix) plain_matrix = np.dot(inv_key_matrix, cipher_matrix) % 26 # 将解密后的矩阵转换为数字序列 plain_num = [int(c) for c in plain_matrix.reshape(1, -1)[0]] # 将数字序列转换为明文 plain_text = ''.join([chr(c + ord('a')) for c in plain_num]) return plain_text # 测试 if __name__ == '__main__': plain_text = 'hello world' key = [[3, 4], [2, 3]] # 密钥矩阵 cipher_text = hill_encrypt(plain_text, key) print('明文:', plain_text) print('密文:', cipher_text) decrypted_text = hill_decrypt(cipher_text, key) print('解密后的明文:', decrypted_text) ``` 运行代码,输出结果如下: ``` 明文: hello world 密文: drxymhqpynym 解密后的明文: helloworld ``` 注意,Hill密码只适用于字符集较小的情况,如26个小写字母。对于更大的字符集,需要使用更复杂的加密算法

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值