希尔(Hill)密码(C语言)
简介
是运用基本矩阵论原理的替换密码,每个字母当作26进制数字:A=0, B=1, C=2… 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果mod26。用作加密的矩阵(即密匙)必须是可逆的,否则就不可能译码。只有矩阵的行列式和26互质,才是可逆的。
C语言实现
#include <stdio.h>
#include <string.h>
#define MAX 60
int main()
{
int K1[2][2] = {0}, K2[2][2] = {0};
int Temp1[2] = {0}, Temp2[2] = {0};
char text[MAX] = {0},result[MAX] = {0};
int T1[MAX] = {0}, T2[MAX] = {0};
int len, flag=0, temp, temp1, i, j, num=0;
/**欢迎**/
printf("--------欢迎使用Hill密码-----------\n");
printf("请填写明文或者密文\n");
scanf("%[^\n]",text);
printf("请选择加密方式,输入1加密,输入2解密\n");
scanf("%d",&num);
printf("请输入密钥k(以空格分开的数组)\n");
for(i=0; i<2; i++)
{
for(j=0; j<2; j++)
{
scanf("%d", &K1[i][j]);
}
}
if(num == 1){
/**加密**/
len = strlen(text);
// 当长度为奇数时补齐一位
if(len % 2 == 1)
{
text[len] = 'a';
len = strlen(text);
flag = 1;
}
// 将大写转成小写,并赋值给T1数组
for(i=0; i<len; i++)
{
if(text[i] >= 'A' && text[i] <= 'Z')
{
text[i] = text[i] + 32;
}
T1[i] = text[i] - 'a';
}
// 得到加密后结果,存储在T2中
for(i=0; i<len; i+=2)
{
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;
}
for(i=0; i<len; i++)
{
result[i] = T2[i] + 'a';
}
printf("明文%s的密文为:%s\n",text,result);
}else if(num == 2){
/**解密**/
len = strlen(text);
// 当长度为奇数时补齐一位
if(len % 2 == 1)
{
text[len] = 'a';
len = strlen(text);
flag = 1;
}
for(i=0; i<len; i++)
{
if(text[i] >= 'A' && text[i] <= 'Z')
{
text[i] = text[i] + 32;
}
T2[i] = text[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;
// 得到解密后结果,存储在T2中
for(i=0; i<len; i+=2)
{
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;
}
for(i=0; i<len; i++)
{
result[i] = T1[i] + 'a';
}
printf("密文%s的明文为:%s\n",text,result);
}
return 0;
}
验证
加密
明文:sunday
密钥k:9 6 7 11
解密
密文:qqihme
密钥k:9 6 7 11
归子莫 发布了69 篇原创文章 · 获赞 96 · 访问量 5933 私信 关注