“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密码的强度在于完全隐藏了单字母的频率。字母和数字的对应也可以更改为其他的方案,使得不容易攻击成功。一般来说,对抗仅有密文的攻击强度较高,但易受到已知明文攻击。

本文出自 “无心的执着” 博客,谢绝转载!

hill密码源代码c语言,古典密码(Hill加密算法)(示例代码)相关推荐

  1. 古典密码算法实验c语言,古典密码实验报告.doc

    古典密码实验报告.doc 哈尔滨工程大学实验报告实验名称古典密码算法班级学号姓名实验时间2014年4月成绩指导教师实验室名称哈尔滨工程大学实验室与资产管理处制一.实验名称古典密码算法2.实验目的通过编 ...

  2. buuctf密码题 传统知识+古典密码

    传统知识+古典密码 BUUCTF上密码题 根据六十甲子年表推出每个值,然后再加60,得到88 90 83 68 77 70 76 90,ASCII码为XZSDMFLZ 又因为题中提到古典密码,所以想到 ...

  3. ECC椭圆密码算法c语言实现,深入浅出椭圆加密算法ECC

    前言 同RSA(Ron Rivest,Adi Shamir,Len Adleman三位天才的名字)一样,ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学)也属于公开 ...

  4. c语言编程实现密码判断,C语言实现密码判断

    在平时应用中,我们常常会需要对于密码的判断,今天Xushine研究院就给大家带来一段代码,这个代码是可扩展的,可以随意自行添加~ #include #include #include #define ...

  5. mysql odbc c语言_C语言ODBC操作MySQL数据库(示例代码)

    数据库及其编程API来源于不同的背景,开发人员可以从众多的数据库中选择一种,每种数据库都有自己的一套编程API,这就为数据库编程造成了很大的局限性.SQL是标准化数据库编程接口的一种尝试,然而各种数据 ...

  6. c语言2048代码linux,C语言实现2048小游戏(示例代码)

    2048 一.设计思路 1.游戏规则 想要制作游戏,首先需要了解游戏的规则,下面就来介绍2048的游戏规则 2048游戏共有16个格子,初始时初始数字由2或者4构成. 手指向一个方向滑动,所有格子会向 ...

  7. 24点游戏c语言链表做法,C语言实现24点程序(示例代码)

    一.简介 本程序的思想和算法来自于C语言教材后的实训项目,程序通过用户输入四个整数计算出能够通过加减乘除得到数字24的所有表达式,程序的设计有别于一般通过穷举实现的方式,效率得到提高.算法介绍如下: ...

  8. mysql的dml全,MySQL数据管理----DML语言(全记住)(示例代码)

    DML语言(全记住) 数据库意义:数据存储.数据管理 DML语言:数据操作语言 Insert update delete truncate 1.insert 添加 错误示例: -- 1.指定1个字段, ...

  9. 字符串解压缩c语言除哈夫曼,C语言实现压缩二例(示例代码)

    一 简单字符串压缩 编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串. 压缩规则: 1.仅压缩连续重复出现的字符.比如字符串"abcbc"由于无连 ...

最新文章

  1. Amazon Aurora是如何设计原生云关系型数据库的?
  2. shell如何将标准错误输出重定向为标准输出
  3. idea里自动创建构造函数
  4. VTK:PolyData之TransformOrderDemo
  5. linux将变量保存生成txt,linux-将输出命令保存在变量中并写入for循环
  6. redis服务器学习一
  7. linux向用户发送消息
  8. 用 man 命令查看 ls 命令的使用手册_Python学习第167课--用man和info打开Linux命令说明书的区别...
  9. Android Editable
  10. nginx封锁恶意IP,并且定时取消的两种脚本
  11. SLAM学习笔记(Code3)----Eigen库中的Geometry
  12. Vue router原理
  13. 计算机基础知识大全之硬件篇
  14. 哪里有电,哪里就应该有网络 ,华为移动路由Pro评测
  15. poi 颜色对照表
  16. 原生Android平板,Remix OS 深入动手玩,这是一个改变 Android 平板使用体验的好系统...
  17. Flutter | 和小老弟一起玩转Widget
  18. 学生考试作弊行为视频实时检测系统源码
  19. 【转载】Hint的常见错误使用方式
  20. NBA比赛结果预测 # 编程大事件 # 嵩天 # python #

热门文章

  1. mongodb $ifNull
  2. .net core linux安装
  3. 如何使用用window.open()
  4. java二叉树转换为链表_leetcode刷题笔记-114. 二叉树展开为链表(java实现)
  5. linux qt getpid,[QTA] Android 动态注入原理分析
  6. 制作双足机器人用易拉罐_小学生手工小制作用易拉罐做飞机模型的方法
  7. 掘金浏览器插件安装图文教程
  8. 【C语言进阶深度学习记录】十六 静态库与动态库的创建与使用
  9. 【常见笔试面试算法题12续集三】动态规划算法案例分析3 LIS练习题(最长上升子序列)
  10. HTML5前端开发学习路线建议,学习前端的必备知识点