目录

希尔密码

1、原理

2、流程图

3、编程实现

4、总结


希尔密码

1、原理

希尔密码是一种运用基本矩阵论原理的代换密码,由Lester S. Hill在1929年发明。

首先将字母转换为数字,将字母分成多个n维向量,跟一个n×n的矩阵相乘,再将得出的结果模26。需要注意的是密钥矩阵必须是可逆的,即矩阵的行列式和26互质。

Hill密码能较好地抵抗统计分析法,对抗唯密文攻击的强度较高,但易受到已知明文攻击。

2、流程图

3、编程实现

        难点:如何根据密钥矩阵求密钥逆矩阵

        行列式可逆的充分条件:方阵的行列式不等于零 在这里行列式的值还需要和26互质 矩阵求逆可以使用伴随矩阵法LU分解法

为了减少计算量和实现难度,这里使用3*3的密钥矩阵。同时伴随矩阵法求逆一般使用下面公式

(行列式值的逆乘以伴随矩阵)

参考:希尔密码  矩阵求逆

        具体代码如下:

        默认输入小写英文字母明文不带空格,以及3*3的密钥矩阵存在逆矩阵且为正整数。(因为这样实现简单。。。)

        主函数:

#include"Hill.h"int main() {while (1) {show();     //菜单界面keyDown();    //按键处理system("pause");system("cls");}
}

Hill.h

#pragma once
#include<cstdio>
#include<iostream>
#include<cstring>
#include<Windows.h>
#include<vector>
using namespace std;
void init();
void show();
void keyDown();
void readFile();
void saveFile();
void encrypt();
void decrypt();
int gcd(int a, int b, int& x, int& y);
int getInv(int a, int m);
void getAntiKey(int key[][3]);

    Hill.cpp 

#include "Hill.h"
string fileStr = "";
string finalStr = "";
int x = 0, y = 0;
int antikey[3][3];//密钥的逆
int key[3][3];//密钥
/*
0 11 15
7 0 1
4 19 0
*/
void init()//初始化
{x = 0;y = 0;fileStr = "";finalStr = "";memset(antikey, 0, sizeof(antikey));memset(key, 0, sizeof(key));
}
void show()
{cout << "*****************希尔密码*****************" << endl;cout << "\t\t1.加密文件" << endl;cout << "\t\t2.解密文件" << endl;cout << "\t\t3.退出" << endl;cout << "******************************************" << endl;}void keyDown()//按键处理
{int userkey = 0;cin >> userkey;switch (userkey) {case 1:cout << "-----------------加密文件-----------------" << endl;readFile();encrypt();saveFile();init();break;case 2:cout << "-----------------解密文件-----------------" << endl;readFile();decrypt();saveFile();init();break;case 3:exit(0);break;}
}void readFile()//读取文件
{cout << "请输入文件名:" << endl;string fileName;cin >> fileName;FILE* fp = fopen(fileName.c_str(), "r+");if (fp == nullptr) {cout << "未找到相关文件" << endl;return;}else {cout << "成功打开文件" << endl;}char ch;int pos = 0;while ((ch = fgetc(fp)) != EOF) {fileStr += ch;}cout << endl << "待处理的文件为:" << endl;cout << fileStr << endl;fclose(fp);
}void saveFile()//保存文件
{string fileName;cout << endl << "请输入要保存信息的文件名:" << endl;cin >> fileName;FILE* fp = fopen(fileName.c_str(), "w+");if (fp == nullptr) {cout << endl << "保存文件失败" << endl;return;}else {cout << endl << "保存成功" << endl;}fprintf(fp, "%s", finalStr.c_str());fclose(fp);}void encrypt()//加密文件
{vector< vector<int> >  c;//明文矩阵vector< vector<int> >  a;//密文矩阵 if (fileStr.size() % 3 == 1)fileStr += "xx";//补充两个if (fileStr.size() % 3 == 2)fileStr += "x";int* m = new int[fileStr.size()];//明文按列分组并转化为数字 //分成多个3个字母的列向量for (int i = 0; i < fileStr.size(); i++) {m[i] = fileStr[i] - 'a';}for (int i = 0; i < fileStr.size(); i += 3) {vector<int> temp = { m[i],m[i + 1],m[i + 2] };c.push_back(temp);}cout << endl << "明文矩阵为:" << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < c.size(); j++) {cout << c[j][i] << " ";//明文矩阵 }cout << endl;}cout << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < c.size(); j++) {cout << char(c[j][i] + 97) << " ";//明文矩阵 }cout << endl;}cout << endl;cout << "请输入密钥矩阵(默认矩阵可逆且为整数)" << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {cin >> key[i][j];}}cout << endl << "按下任意键进行加密" << endl;char ch = getchar(); ch = getchar();//矩阵乘法for (int i = 0; i < c.size(); i++) {//矩阵的列数 vector<int> temp;for (int j = 0; j < 3; j++) {int pos = 0;for (int k = 0; k < 3; k++) {pos += key[j][k] * c[i][k];}temp.push_back((pos) % 26);}a.push_back(temp);}cout << "密文矩阵" << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < a.size(); j++) {cout << a[j][i] << " ";//密文矩阵 }cout << endl;}cout << endl;for (int i = 0; i < a.size(); i++) {for (int j = 0; j < a[0].size(); j++) {finalStr += char(a[i][j] + 97);}}delete[]m;cout << endl << "得到的密文为:" << endl;cout << finalStr << endl;
}void decrypt()//解密文件
{vector< vector<int> >  c;//密文矩阵vector< vector<int> >  a;//明文矩阵 int* m = new int[fileStr.size()];//密文按列分组并转化为数字 //分成多个3个字母的列向量for (int i = 0; i < fileStr.size(); i++) {m[i] = fileStr[i] - 'a';}for (int i = 0; i < fileStr.size(); i += 3) {vector<int> temp = { m[i],m[i + 1],m[i + 2] };c.push_back(temp);}cout << endl << "密文矩阵为:" << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < c.size(); j++) {cout << c[j][i] << " ";//密文矩阵 }cout << endl;}cout << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < c.size(); j++) {cout << char(c[j][i] + 97) << " ";//密文矩阵 }cout << endl;}cout << endl;cout << "请输入密钥矩阵(默认矩阵可逆且为整数)" << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {cin >> key[i][j];}}getAntiKey(key);//求逆矩阵cout << endl << "成功求出密钥矩阵的逆" << endl;//密钥矩阵的逆矩阵for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {cout << antikey[i][j] << " ";}cout << endl;}cout << endl << "按下任意键进行解密" << endl;char ch = getchar(); ch = getchar();//矩阵乘法for (int i = 0; i < c.size(); i++) {//矩阵的列数 vector<int> temp;for (int j = 0; j < 3; j++) {int pos = 0;for (int k = 0; k < 3; k++) {pos += antikey[j][k] * c[i][k];}temp.push_back((pos) % 26);}a.push_back(temp);}cout << "解密后的矩阵" << endl;for (int i = 0; i < 3; i++) {for (int j = 0; j < a.size(); j++) {cout << a[j][i] << " ";}cout << endl;}cout << endl;for (int i = 0; i < a.size(); i++) {for (int j = 0; j < a[0].size(); j++) {finalStr += char(a[i][j] + 97);}}delete[]m;cout << endl << "得到的明文为:" << endl;cout << finalStr << endl;
}int gcd(int a, int b, int& x, int& y)//求最大公约数
{if (b == 0) {x = 1;y = 0;return a;}int g = gcd(b, a % b, x, y);int temp = x;x = y;y = temp - (a / b) * y;return g;
}int getInv(int a, int m)//求乘法逆元
{gcd(a, m, x, y);return (x % m + m) % m;
}void getAntiKey(int key[][3]) {//求行列式值 int v1 = key[0][0] * (key[1][1] * key[2][2] - key[1][2] * key[2][1]);int v2 = -key[0][1] * (key[1][0] * key[2][2] - key[2][0] * key[1][2]);int v3 = key[0][2] * (key[1][0] * key[2][1] - key[1][1] * key[2][0]);//cout<<v1<<" "<<v2<<" "<<v3<<endl;int d = (v1 + v2 + v3) % 26;//cout<<d<<endl;int dinv = getInv(d, 26);//cout<<dinv<<endl;//求伴随矩阵 int temp[4];for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {memset(temp, 0, sizeof(temp));int pos = 0;for (int x = 0; x < 3; x++) {for (int y = 0; y < 3; y++) {if (x != i && y != j) {temp[pos++] = key[x][y];}}}int cur = pow(-1, i + 1 + j + 1) * (temp[0] * temp[3] - temp[2] * temp[1]);antikey[j][i] = (dinv * (cur % 26 + 26)) % 26;}}}

4、总结

通过采用线性代数中的矩阵乘法运算和逆运算,能够较好地抵抗频率分析,很难被攻破。当加密矩阵的阶数n越大,破译的难度就会增大,此时计算量也大。

希尔密码体系为破译者至少设置了三道关口,加大了破译难度。破译希尔密码的关键是猜测文字被转换成几维向量(列矩阵的行数)、所对应的字母表是怎样排列的,更为重要的是要设法获取加密矩阵A。要破解密码,向量的维数、字母的排列表和加密矩阵三者缺一不可。(百度百科)

希尔密码(原理+代码)相关推荐

  1. C++希尔密码的实现以及运用

    希尔密码(Hill Cipher)是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明.每个字母当作26进制数字:A=0, B=1, C=2... 一串字母当成n维向量,跟一 ...

  2. Visual Studio 2019下用 C# 实现 Hill2 二阶希尔密码 的加密、解密 GUI界面

    1.什么是Hill2 什么是Hill密码 希尔密码(Hill)使用每个字母在字母表中的顺序作为其对应的数字,即 A=0,B=1,C=2 等,然后将明文转化为 n 维向量,跟一个 n × n 的矩阵相乘 ...

  3. CTF-Crypto 密码原理及解密方法

    CTF-Crypto 密码原理及解密方法 文章目录 CTF-Crypto 密码原理及解密方法 推荐综合加解密网址 一.常见密码格式 二.古典密码 凯撒密码 仿射密码 埃特巴什码 培根密码 棋盘密码 希 ...

  4. 深入 WEP和 WPA密码原理

    深入 WEP和 WPA密码原理 1 概述 目前情况下: WEP的破解为利用加密体制缺陷,通过收集足够的数据包,使用分析密算法还原出密码. WPA目前没有加密体制的缺陷可被利用,破解WPA密码使用的是常 ...

  5. 深入 WEP和 WPA密码原理 1

    深入 WEP和 WPA密码原理   1  概述  目前情况下: WEP的破解为利用加密体制缺陷,通过收集足够的数据包,使用分析密算法还原出密码. WPA目前没有加密体制的缺陷可被利用,破解WPA密码使 ...

  6. CTF-Crypto-各种密码原理及解密方法

    CTF-Crypto-各种密码原理及解密方法 一.常见密码格式(太懒了,待补充) 二.古典密码 凯撒密码 仿射密码 埃特巴什码 培根密码 棋盘密码 希尔密码 维吉尼亚密码 摩尔斯密码 栅栏密码(普通型 ...

  7. 希尔密码在CTF中应用—记一道题

    CTF-crypto 解题思路来自:i春秋的大佬们 https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=52687&highli ...

  8. java代码实现希尔排序_Java希尔排序算法代码实现

    Java希尔排序算法代码实现 时间:2017-08-30     来源:华清远见JAVA学院 什么是Java希尔排序算法呢? 希尔排序算法实际上是一种分组插入的排序算法,又被称为缩小增量排序.今天华清 ...

  9. 浏览器记住密码--原理/不记住密码的方法

    原文网址:浏览器记住密码--原理/不记住密码的方法_IT利刃出鞘的博客-CSDN博客 简介 本文介绍浏览器是如何自动跳出保存密码的提示的,并介绍如何让浏览器不自动跳出保存密码的提示的方法. 记住密码的 ...

  10. python 靶心_手把手教你使用Python实战反欺诈模型|原理+代码

    原标题:手把手教你使用Python实战反欺诈模型|原理+代码 作者 | 萝卜 来源 | 早起Python(ID: zaoqi-python) 本文将基于不平衡数据,使用Python进行 反欺诈模型数据 ...

最新文章

  1. BahdanauAttention与LuongAttention注意力机制简介
  2. Github无法加载或不显示图片问题
  3. IDEA快捷键拆解系列(五):Navigate篇
  4. ubuntu获取root权限_群辉 SSH 获取 root 权限
  5. 最长上升子序列问题 (LIS)
  6. boost::describe模块实现string转enum的测试程序
  7. 删除python的注册表_Python操作注册表详细步骤介绍
  8. 蓝桥杯 ALGO-79 算法训练 删除数组零元素
  9. python 字符串加密 唯一数字_python实现字符串加密 生成唯一固定长度字符串
  10. Hbase常用shell
  11. mongodb python 大于_菜鸟成长记--如何根据关键词爬取微博内容?(scrapy+mongodb)
  12. 【日常】有道云笔记markdown数学公式格式转换脚本
  13. Spring ioc 详解
  14. Centos7安装Nginx监控组件Nginx-rrd【二】
  15. 恢复win10系统默认服务器,解决win10系统“重置电脑时出现问题 未进行任何更改”的方法...
  16. OpenGL shader笔记
  17. chrome表单自动填充默认样式-autofill
  18. Heap和Heapify
  19. C语言 ltoa sprintf strcat
  20. 兰州大学信息与计算机科学硕,兰州大学信息科学与工程学院

热门文章

  1. 报童问题求解最大利润_Ortools调用第三方求解器
  2. 台达服务器电源原理电路图,六款简单的开关电源电路设计原理图详解
  3. shark恒破解笔记4-API断点GetPrivateProfileStringA
  4. 用于温度测量的热敏电阻
  5. python连接微信运动_怎样读取微信运动数据接口?
  6. 玩转代码|简单分析如何获取小程序的t值
  7. 用计算机从85加到98的和是,2018年职称计算机考试题库及答案
  8. 微信小程序中,数字等宽字体
  9. python之操作mysql数据库
  10. JAVA从入门到放弃01