“Hill的加密与解密”
Hill加密是另一种多字母代替密码,与多表代替密码不同的是,Hill密码要求将明文分成同等规模的若干个分组(最后一个分组涉及到填充),每一个分组被整体的加密代换,即希尔密码属于分组加密。Hill密码的算法思想是:将一个分组中的d个连续的明文字母通过线性变换转换为d个密文字母。这种变换由d个线性方程决定,其中每个字母被分配一个数值(0,1,。。。,25)。解密只需要做一次逆变换就可以了,密钥就是变换矩阵本身。
设明文为一维矩阵m,密文为一维矩阵c,密钥用k矩阵表示,则:
即密文分组=明文分组*密钥矩阵。
本程序使用的密钥是:
下面是具体的源程序:—头文件:classical.h
#pragma once
//古典密码之希尔加密
#include
#include
#define ROW 4 //行
#define COL 4 //列
int* plus(int(*K)[COL], int * num) //进行加密
{
int *arr = (int *)calloc(sizeof(int),4);
int sum = 0;
int sub = 0;
for (int i = 0; i
{
for (int j = 0; j
{
sum = (*(num + j)) * (*(*(K + j) + i));
sub = sub + sum;
}
arr[i] = (arr[i] + sub) % 26;
sub = 0;
}
return arr;
}
int fun(int i, int j, int(*K)[COL]) //求伴随矩阵
{
int num = 0;
int arr[ROW][COL] = { 0 };
int left = 0;
int right = 0;
for (int k1 = 0; k1
{
for (int k2 = 0; k2
{
if (k1
{
arr[k1][k2] = *(*(K + k1) + k2);
}
else if (k1 j)
{
arr[k1][k2 - 1] = *(*(K + k1) + k2);
}
else if (k1 > i && k2 > j)
{
arr[k1 - 1][k2 - 1] = *(*(K + k1) + k2);
}
else if (k1 > i && k2
{
arr[k1 - 1][k2] = *(*(K + k1) + k2);
}
}
}
left = arr[1][1] * arr[2][2] * arr[0][0] + arr[0][1] * arr[1][2] * arr[2][0]
+ arr[1][0] * arr[2][1] * arr[0][2];
right = arr[0][2] * arr[1][1] * arr[2][0] + arr[0][1] * arr[1][0] * arr[2][2]
+ arr[0][0] * arr[1][2] * arr[2][1];
num = pow((double)(-1), (i + 1) + (j + 1)) * (left - right);
return num;
}
int* answer(int(*K)[COL], int * str, int det) //希尔解密
{
int ptr[ROW][COL] = { 0 }; //ptr为逆矩阵
int* ans = (int *)calloc(sizeof(int), 4);
int sum = 0;
int sub = 0;
int bag = 0;
for (int i = 0; i
{
for (int j = 0; j
{
bag = fun(i, j, K) / (det);
if (bag
{
ptr[j][i] = (26 + bag) % (26);
}
else
{
ptr[j][i] = bag % (26);
}
}
}
for (int i = 0; i
{
for (int j = 0; j
{
sum = (*(str + j)) * ptr[j][i];
sub = sub + sum;
}
ans[i] = (ans[i] + sub) % 26;
sub = 0;
}
return ans;
}
void menu() //菜单
{
printf(" ——古典密码 \n\n");
printf("********** 1.加密 *******\n");
printf("********** 2.解密 *******\n");
printf("********** 0:退出 *******\n");
printf("请选择:");
}
char* inputclear() //输入明文
{
printf("请输入明文:");
char num[20] = {‘\n‘};
char *ptr = num;
int i = 0;
char ch;
fflush(stdin); //清除缓冲区
while ((ch = getchar()) != ‘\n‘)
{
num[i] = ch;
i++;
}
return ptr;
}
char* inputsecret() //输入密文
{
printf("请输入密文:");
char num[20] = { ‘\n‘ };
char *ptr = num;
int i = 0;
char ch;
fflush(stdin); //清除缓冲区
while ((ch = getchar()) != ‘\n‘)
{
num[i] = ch;
i++;
}
return ptr;
}
void judge(int n, int(*K)[4]) //处理加密或解密
{
char *ptr, *pln;
int src[20];
int num[4] = { 0 };
int *parr = NULL;
int *pnum = NULL;
int det = -1; //计算K的行列式的值
switch (n)
{
case 1: //加密
ptr = inputclear();
for (int i = 0; i
{
if (*ptr != ‘\n‘ && *ptr != EOF)
{
src[i] = *(ptr + i) - ‘A‘;
}
else
{
break;
}
}
printf("加密后得到的密文:");
pnum = src;
while (*pnum >= 0 && *pnum <= 25)
{
for (int i = 0; i
{
num[i] = *(pnum + i);
}
parr = plus(K, num);
for (int j = 0; j
{
printf("%c", *(parr+j) + ‘A‘);
}
pnum = pnum + ROW;
}
printf("\n");
free(parr);
break;
case 2:
pln = inputsecret();
for (int i = 0; i
{
if (*pln != ‘\n‘ && *pln != EOF)
{
src[i] = *(pln + i) - ‘A‘;
}
else
{
break;
}
}
printf("解密后得到的明文:");
pnum = src;
while (*pnum >= 0 && *pnum <= 25)
{
for (int i = 0; i
{
num[i] = *(pnum + i);
}
parr = answer(K, num, det);
for (int j = 0; j
{
printf("%c", *(parr + j) + ‘A‘);
}
pnum = pnum + ROW;
}
printf("\n");
free(parr);
break;
case 0:
exit(EXIT_FAILURE);
default:
break;
}
}
—源文件:test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
//希尔加密
#include
#include
#include "classical.h"
int main()
{
int K[4][4] = { { 8, 6, 9, 5 }, { 6, 9, 5, 10 }, { 5, 8, 4, 9 }, { 10, 6, 11, 4 } }; //密钥
int left=K[0][0] * K[1][1] * K[2][2] * K[3][3] + K[1][0] * K[0][3] * K[3][2] * K[2][1]+ K[2][0] * K[3][1] * K[0][2] * K[1][3] + K[3][0] * K[0][1] * K[1][2] * K[2][3];
int right = K[0][3] * K[1][2] * K[2][1] * K[3][0] + K[0][0] * K[1][3] * K[2][2] *
K[3][1]+ K[0][1] * K[1][0] * K[2][3] * K[3][2] + K[0][2] * K[1][1] * K[2][0] * K[3][3];
int n = 0;
menu();
scanf("%d", &n);
judge(n, K);
system("pause");
return 0;
}
—运行结果:
Hill加密:
Hill解密:
很明显,Hill密码将解密的长消息分组,分组的长度取决于密钥矩阵的维数,Hill密码的强度在于完全隐藏了单字母的频率。字母和数字的对应也可以更改为其他的方案,使得不容易攻击成功。一般来说,对抗仅有密文的攻击强度较高,但易受到已知明文攻击。
本文出自 “无心的执着” 博客,谢绝转载!