用C写希尔密码的加解密及求解密钥,其中密钥为3*3的矩阵
时间: 2024-01-22 08:18:27 浏览: 129
以下是用C语言实现希尔密码的加解密及求解密钥的代码,密钥为3x3的矩阵:
```c
#include<stdio.h>
#include<string.h>
// 加密函数
void encrypt(char *str, int key[3][3])
{
int i, j, k = 0;
int len = strlen(str);
int ciphertext[len];
for(i=0; i<len; i+=3) {
// 将三个字符转化为一个整数
int pt[3];
for(j=0; j<3; j++) {
if(i+j < len) {
pt[j] = str[i+j];
} else {
pt[j] = 'X';
}
}
int pt_num = pt[0]*100 + pt[1]*10 + pt[2];
// 与密钥矩阵相乘
int ct_num = 0;
for(j=0; j<3; j++) {
for(k=0; k<3; k++) {
ct_num += pt[j] * key[j][k];
}
}
ciphertext[i] = ct_num / 100;
ciphertext[i+1] = (ct_num % 100) / 10;
ciphertext[i+2] = ct_num % 10;
}
printf("密文为:");
for(i=0; i<len; i++) {
printf("%c", ciphertext[i]);
}
printf("\n");
}
// 解密函数
void decrypt(char *str, int key[3][3])
{
int i, j, k = 0;
int len = strlen(str);
int plaintext[len];
for(i=0; i<len; i+=3) {
// 将三个字符转化为一个整数
int ct[3];
for(j=0; j<3; j++) {
if(i+j < len) {
ct[j] = str[i+j];
} else {
ct[j] = 'X';
}
}
int ct_num = ct[0]*100 + ct[1]*10 + ct[2];
// 与密钥矩阵的逆矩阵相乘
int pt_num = 0;
int inv_key[3][3];
int det = 0;
for(j=0; j<3; j++) {
inv_key[j][0] = key[(j+1)%3][(k+1)%3] * key[(j+2)%3][(k+2)%3] - key[(j+1)%3][(k+2)%3] * key[(j+2)%3][(k+1)%3];
det += key[j][k] * inv_key[j][0];
inv_key[j][1] = key[(j+1)%3][(k+2)%3] * key[(j+2)%3][(k+0)%3] - key[(j+1)%3][(k+0)%3] * key[(j+2)%3][(k+2)%3];
det += key[j][(k+1)%3] * inv_key[j][1];
inv_key[j][2] = key[(j+1)%3][(k+0)%3] * key[(j+2)%3][(k+1)%3] - key[(j+1)%3][(k+1)%3] * key[(j+2)%3][(k+0)%3];
det += key[j][(k+2)%3] * inv_key[j][2];
}
if(det == 0) {
printf("密钥不可逆,无法解密!\n");
return;
}
for(j=0; j<3; j++) {
for(k=0; k<3; k++) {
inv_key[j][k] /= det;
}
}
for(j=0; j<3; j++) {
pt_num += ct[j] * inv_key[0][j];
}
for(j=0; j<3; j++) {
pt_num += ct[j] * inv_key[1][j];
}
for(j=0; j<3; j++) {
pt_num += ct[j] * inv_key[2][j];
}
plaintext[i] = pt_num / 100;
plaintext[i+1] = (pt_num % 100) / 10;
plaintext[i+2] = pt_num % 10;
}
printf("明文为:");
for(i=0; i<len; i++) {
printf("%c", plaintext[i]);
}
printf("\n");
}
// 求解密钥函数
void get_key(int key[3][3])
{
printf("请输入3x3的矩阵作为密钥:\n");
int i, j;
for(i=0; i<3; i++) {
for(j=0; j<3; j++) {
scanf("%d", &key[i][j]);
}
}
// 检查密钥是否可逆
int det = key[0][0] * (key[1][1]*key[2][2] - key[1][2]*key[2][1])
- key[0][1] * (key[1][0]*key[2][2] - key[1][2]*key[2][0])
+ key[0][2] * (key[1][0]*key[2][1] - key[1][1]*key[2][0]);
if(det == 0) {
printf("密钥不可逆,请重新输入!\n");
get_key(key);
}
}
int main()
{
int key[3][3];
char str[100];
printf("请输入要加密的明文:\n");
scanf("%s", str);
get_key(key);
encrypt(str, key);
decrypt(str, key);
return 0;
}
```
需要注意的是,该代码中求解密钥的函数`get_key`只能处理可逆的密钥矩阵,如果输入的矩阵不可逆,程序会提示重新输入。
阅读全文