Hill密码的加密、解密与破译
- 格式:ppt
- 大小:173.00 KB
- 文档页数:13
Hill 密码的加密、解密和破译 实验报告吴林柱 5100309888实验任务2、利用所介绍的Hill 密码体制原理,根据所给定的26个英文字母的乱序表值(见表),设计与Hill 4密码体制的加密、解密与破译框图并建立必要的计算机程序。
设英文26个字母以下的乱序表与Z 26中的整数对应: A B C D E F G H I J K L M 5 23 2 20 10 15 8 4 18 25 0 16 13 N O P Q R S T U V W X Y Z 731196122421171422119(1)设⎪⎪⎪⎪⎪⎭⎫⎝⎛=4116109485105965968A ,验证矩阵A 能否作为Hill 4,用框图画出你的验算过程,并编写相应的计算机程序。
(2)设明文为HILL CRYPTOGRAPHIC SYSTEM IS TRADITIONAL 。
利用上面的表值与加密矩阵给此明文加密,并将得到的密文解密。
画出加密与解密过程的框图并编写相应的计算机程序。
(3)已知在上述给定值下的一段密文为JCOWZLVBDVLEQMXC ,对应的明文为DELAY OPERATIONSU 。
能否确定对应的加密矩阵?给出你的判断过程。
4、如下的密文据表10.1以Hill 加密,密文为VIKYNOTCLKYRJQETIRECVUZLNOJTUYDI MHRFITQ 。
已获知其中相邻字母LK 表示字母KE ,试破译这份密文。
5、找出元素属于Z 26的所有可能的Hill 密码加密矩阵。
若截获了如下一段密文UTCQCVFOYQUVMGMGULFOLEYHDUDOPEASWXTIFBAMWT 且知他是根据表10.1按Hill 密码 体制加密的,能否破译?实验解答2、(1)由定义可知,元素属于Z m 的方阵A 模m 可逆的充要条件是,m 和det A 没有公共素因子。
因此,框图如下:求矩阵A 的行列式 det A 若det A 与26没有公共素因子,则A 可用。
Hill密码本⽂为转载他⼈⽂章这⾥主要介绍的是:古典密码之 hill密码加密解密过程的编程实现。
⾸先,请看对我对hill密码做的简单介绍。
hill密码是古典密码中多表代换密码部分的重要⼀环,以下的介绍节选⾃百度,想要深⼊了解的请查阅书籍补充相关知识。
原理:希尔密码(Hill Password)是运⽤基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明。
每个字母当作26数字:A=0, B=1, C=2...⼀串字母当成n维向量,跟⼀个n×n的矩阵相乘,再将得出的结果模26。
注意⽤作加密的矩阵(即密匙)在\mathbb_^n必须是可逆的,否则就不可能译码。
只有矩阵的和26,才是可逆的。
需要的知识储备:1)线性代数基础知识.2) 基础知识.约定:1)希尔密码常使⽤Z26字母表,在此贴中,我们也以Z26最为字母表进⾏讲解.在附带源码中有两种字母表选择.2) ⼤家都知道最⼩的质数是2,1 既不是质数也不是合数. 在此我们定义1对任何质数的模逆为其本⾝.因为对于任意质数n,有: 1*1 % n = 1 的. 也应该是很好理解的.过程:1)加密:密⽂=明⽂*密钥矩阵(注:明⽂要被分割成与密钥维数相同的⼀维⾏列式)2)解密:明⽂=密⽂*密钥矩阵的逆(注:要求与加密过程相同)加密解密过程如下图:例:加密过程:解密:对上述过程进⾏编程,主要的函数声明如下:12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25/*** 头⽂件名称:hillcrypto.h* 实现⽂件名称:hillcrypto.cpp* 项⽬名称:多表代换密码之hill密码* 作者:邹明* 完成时间:2016.3.14**/#ifndef __HILLCRTPTO_H__#define __HILLCRTPTO_H__#include<iostream>using namespace std;#include<assert.h>#include <iomanip>#define ROW 4 //密钥⾏数为4#define COV 4 //密钥列数为4void InputKeys(float keys[ROW][COV]); //输⼊密钥void InputWords(char*words); //输⼊明⽂void InputObwords(char*words); //输⼊密⽂void PopKeys(float keys[ROW][COV]); //输出密钥void Encryption(float keys[ROW][COV], char*words, char*crypto); //明⽂加密2526 27 28 29 30 31 32 33void Encryption(float keys[ROW][COV], char*words, char*crypto); //明⽂加密void Decode(float keys[ROW][COV], char*words, char*crypto); //密⽂解密bool Gauss(float A[ROW][COV], float B[ROW][COV], int n); //⾼斯消去法求逆矩阵void ObMatrix(float a[ROW][COV], float b[ROW][COV], int n); //求密钥逆矩阵void menu(); //菜单#endif函数实现过程中的主函数实现以及菜单函数实现如下:12345 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56/* 实现⽂件名称:hillcrypto.cpp */#include"hillcrypto.h"int main(){menu(); //菜单+选择system("pause");return0;}void menu(){float keys[ROW][COV] = { 8, 6, 9, 5, 6, 9, 5, 10, 5, 8, 4, 9, 10, 6, 11, 4 }; //加密矩阵(默认密钥) float obkeys[ROW][COV] = { 0 }; //解密矩阵(密钥逆矩阵)char words[100] = { 0 };char crypto[100] = { 0 };char obwords[100] = { 0 };bool flag = true; //菜单选择bool chose = false; //密钥选择char cn = 0;while(flag){int n = 0;cout << endl;cout << "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<< endl;cout << "\t\t\t1.输⼊密钥"<< endl;cout << "\t\t\t2.明⽂加密"<< endl;cout << "\t\t\t3.密⽂解密"<< endl;cout << "\t\t\t4.退出"<< endl << endl;cout << "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<< endl;cout << "请选择->:";cin >> n;switch(n){case1:system("cls");cout << "默认密钥为:";PopKeys(keys);cout << "请问您要重新输⼊密钥? y/n"<< endl << "请选择->:";cin >> cn;if((cn == 'y') || (cn == 'Y')){InputKeys(keys); //输⼊密钥}else if((cn == 'n') || (cn == 'N')){cout << "感谢您选择使⽤默认密钥!"<< endl;}elsecout << "输⼊有误,请重新选择!"<< endl;system("pause");break;case2:system("cls");InputWords(words); //输⼊明⽂Encryption(keys, words, crypto); //加密cout << "密⽂是->:"<< crypto << endl;56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 cout << "密⽂是->:"<< crypto << endl;system("pause");break;case3:system("cls");InputObwords(crypto); //输⼊密⽂ObMatrix(keys, obkeys, COV); //计算解密矩阵 Decode(obkeys, obwords, crypto); //解密cout << "明⽂是->:"<< obwords << endl;system("pause");break;case4:system("cls");cout << endl << endl << endl;cout << setw(15) << "谢谢使⽤!"<< endl;flag = false;system("pause");break;default:cout << "选择有误,请重新选择!"<< endl;system("pause");break;}}}输⼊明⽂函数和输⼊密⽂函数:123456 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40void InputWords(char*words) //输⼊明⽂{assert(words);cout << "请输⼊明⽂:";char*start = words;int flag = 1;getchar();while(flag){*words = getchar();words++;if(*(words - 1) == '\n'){*words = '\0';flag = 0;}}words = start;while(*start){if(('A'<= *start) && (*start <= 'Z')){*words = *start;words++;}else if(('a'<= *start) && (*start <= 'z')) {*words = *start - 32;words++;}start++;}*words = '\0';cout << "输⼊成功!"<< endl;}void InputObwords(char*words) //输⼊密⽂{assert(words);cout << "请输⼊密⽂:";char*start = words;40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 char*start = words;int flag = 1;getchar();while(flag){*words = getchar();words++;if(*(words - 1) == '\n'){*words = '\0';flag = 0;}}words = start;while(*start){if(('A'<= *start) && (*start <= 'Z')){*words = *start;words++;}else if(('a'<= *start) && (*start <= 'z')) {*words = *start - 32;words++;}start++;}*words = '\0';cout << "输⼊成功!"<< endl;}输⼊密钥与输出密钥函数:12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26void InputKeys(float keys[ROW][COV]) //输⼊密钥{cout << "请输⼊密钥:"<< endl;for(size_t i = 0; i < ROW; i++){cout << "请输⼊第"<< i << "⾏密钥("<<ROW<<"个数):"; for(size_t j = 0; j < COV; j++){cin >> keys[i][j];}}cout << "输⼊成功 !"<< endl;}void PopKeys(float keys[ROW][COV]) //输出密钥{cout << "密钥为:"<< endl;for(size_t i = 0; i < ROW; i++){for(size_t j = 0; j < COV; j++){cout << keys[i][j] << " ";}cout << endl;}}加密函数:123 4 5void Encryption(float keys[ROW][COV], char*words, char*crypto) //加密函数{assert(words);int len = strlen(words);5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 int len = strlen(words);char*start = words;while(len > 0){int matrix[ROW] = { 0 };for(int i = 0; i < ROW; i++){if(*start)matrix[i] = *start - 'A';elsematrix[i] = 0;start++;}len -= ROW;int cry[ROW] = { 0 };for(int i = 0; i < ROW; i++){int temp = 0;for(int j = 0; j < COV; j++){temp = matrix[j] * keys[j][i] + temp; }cry[i] = temp % 26;*crypto = 'A'+ cry[i]; //计算密⽂crypto++;}}}解密函数,以及求逆矩阵函数:1234567891011 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39void Decode(float obkeys[ROW][COV], char*words, char*crypto)//解密函数{assert(crypto);int len = strlen(crypto);char*start = crypto;while(len > 0){int matrix[ROW] = { 0 };for(int i = 0; i < ROW; i++){if(*start)matrix[i] = *start - 'A';elsematrix[i] = 0;start++;}len -= ROW;int cry[ROW] = { 0 };for(int i = 0; i < ROW; i++){int temp = 0;for(int j = 0; j < COV; j++){temp = matrix[j] * obkeys[j][i] + temp;}cry[i] = temp % 26;*words = 'A'+ cry[i]; //计算明⽂words++;}}}39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107void ObMatrix( float a[ROW][COV], float b[ROW][COV], int n) //求逆矩阵函数{int i, j; //定义矩阵的⾏列式if(Gauss(a, b, n)){cout << "该⽅阵的逆矩阵为: \n";for(i = 0; i < n; i++){cout << setw(4);for(j = 0; j < n; j++){int temp =b[i][j]/ 1;float num = b[i][j] - temp;if(fabs(num) < 0.50)b[i][j] = (int)temp;elseb[i][j] = temp + (int)(num * 2);cout << b[i][j] << setw(10);}cout << endl;}}cout << "逆矩阵(mod26):"<< endl;for(int i = 0; i < ROW; i++){cout << setw(4);for(int j = 0; j < COV; j++){if(b[i][j] >= 0){b[i][j] = (int)b[i][j] % 26;}else{b[i][j] = 26 + (int)b[i][j] % 26;}cout << b[i][j] << setw(6);}cout << endl;}}bool Gauss(float A[ROW][COV], float B[ROW][COV], int n) //⾼斯消去法{int i, j, k;float max, temp;float t[ROW][COV]; //临时矩阵//将A矩阵存放在临时矩阵t[n][n]中for(i = 0; i < n; i++){for(j = 0; j < n; j++){t[i][j] = A[i][j];}}//初始化B矩阵为单位阵for(i = 0; i < n; i++){for(j = 0; j < n; j++){B[i][j] = (i == j) ? (int)1 : 0;}}for(i = 0; i < n; i++){//寻找主元max = t[i][i];k = i;for(j = i + 1; j < n; j++){if(fabs(t[j][i]) > fabs(max)){max = t[j][i];k = j;}}107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 }//如果主元所在⾏不是第i⾏,进⾏⾏交换if(k != i){for(j = 0; j < n; j++){temp = t[i][j];t[i][j] = t[k][j];t[k][j] = temp;//B伴随交换temp = B[i][j];B[i][j] = B[k][j];B[k][j] = temp;}}//判断主元是否为0, 若是, 则矩阵A不是满秩矩阵,不存在逆矩阵 if(t[i][i] == 0){cout << "There is no inverse matrix!";return false;}//消去A的第i列除去i⾏以外的各⾏元素temp = t[i][i];for(j = 0; j < n; j++){t[i][j] = t[i][j] / temp; //主对⾓线上的元素变为1B[i][j] = B[i][j] / temp; //伴随计算}for(j = 0; j < n; j++) //第0⾏->第n⾏{if(j != i) //不是第i⾏{temp = t[j][i];for(k = 0; k < n; k++) //第j⾏元素 - i⾏元素*j列i⾏元素 {t[j][k] = t[j][k] - t[i][k] * temp;B[j][k] = B[j][k] - B[i][k] * temp;}}}}return true;}程序运⾏结果:选择:1选择:y选择:n选择 2.明⽂加密:选择 3.密⽂解密:选择 4.退出:。
hill密码算法原理
Hill密码算法是一种基于线性代数的分组对称密码算法,它的
核心原理是将明文分成几个字母一组,然后利用矩阵乘法来实现加密和解密过程。
具体原理如下:
1. 密钥生成:选择一个正整数n,然后随机生成一个n×n的矩
阵K作为密钥矩阵。
2. 加密过程:
a. 将明文分组,每组n个字母。
如果最后一组不足n个字母,可以通过添加空格等方式补齐。
b. 将每个明文分组转换为一个列向量X,即向量X的每个元
素对应一个字母的数值,可以使用ASCII码表进行转换。
c. 对于每个明文向量X,进行矩阵乘法运算:C = K * X,其
中C为密文向量。
d. 将得到的密文向量C转换回字母形式。
3. 解密过程:
a. 将密文分组,每组n个字母。
b. 对于每个密文向量Y,进行矩阵乘法运算:X = K^-1 * Y,其中X为解密后的明文向量。
c. 将得到的明文向量X转换回字母形式。
需要注意的是,密钥矩阵K必须是可逆的,否则解密过程无
法正确进行。
同时,由于矩阵乘法运算的特性,对于某些明文分组,可能存在明文和密文相同的情况,这被称为"Hill同态"。
为了避免这种情况,通常会对字母表进行扩展或使用其他技巧进行加密。
Hill密码加密的密文破译姓名:谭周兴学号:13091076明文:breathtaking密文:RUPOTENTOIFVHill密码:将明文的每个字母当作26进制数字:A=0, B=1, C=2... 一串字母当成n 维向量,跟一个n×n的矩阵M相乘,再将得出的结果MOD26,得到密文。
密钥矩阵M必须是在Z26上可逆才能译码。
明文对应的数字:1,17,4,0,19,7,19,0,10,8,13,6密文对应的数字:17,20,15,14,19,4,13,19,14,8,5,21分析:一共有12位数字,则密钥矩阵可能是1*1、2*2、3*3、4*4、6*6、12*12(为12的因子)维的。
根据已有的明密文不能破译4*4及其以上的密钥矩阵,另外明文里面含有0,从而排除1*1的情况,因而考虑2*2阵和3*3阵。
1、2*2矩阵:将明文按行写成一些2*2矩阵,如A1=[11740],B=[17201514]。
A1M(mod26)=B,矩阵A1在实数域内是可逆矩阵,判断A1在Z26上是否可逆,计算det(A1)(mod 26)=10,与26不互素,故A1不可逆,M无法根据A1得到。
继续上述步骤,A2=[40197]。
计算det(A2)(mod 26)=2,与26不互素,故A2不可逆,M无法根据A2得到。
det(A3)(mod 26)=23,和M互素,如图计算A3的代数余子式A*=(detA)*A-1mod26(矩阵元素元素属于实数域)和A-1.A-1=A*|A|-1(这里的矩阵元素和行列式的逆属于Z26.|A|-1计算用如下代码即可:#include<stdio.h>void main(){int i,a;scanf("%d",&a);for(i=0;i<=25;i++){if((a*i)%26==1)break;}printf("%d",i);}算得M=[13 1;12 9]。
Hill密码(Java)Hill密码是⼀种传统的密码体系。
加密原理:选择⼀个⼆阶可逆整数矩阵A称为密码的加密矩阵,也就是这个加密体系的密钥。
加密过程: 明⽂字母依次逐对分组,例如加密矩阵为⼆阶矩阵,明⽂就两个字母⼀组,如果最后⼀组不⾜(明⽂长度为奇数),就补充任意字母凑个双,构成⼆维向量组a。
计算矩阵A乘以向量组a,得到新的⼆维列向量b,反查字母表得到两个字母即为密⽂字母。
也就是说,加密过程为:明⽂-->映射为数字矩阵-->经过矩阵加密-->映射为字符串(密⽂)解密过程也是同样的过程,只不过中间使⽤矩阵解密,Hill密码是⼀种传统的密码体系。
根据这个过程,每⼀阶段功能代码如下:⾸先创建⼀个类,HillCrypto,成员变量有加密密钥矩阵和解密密钥矩阵,字母转数值映射和数值转字母映射初始化阶段,实例化以上成员变量,其中映射表较⼤,因此写在了本地⽂件中便于重⽤,创建映射时需要读取本地⽂件。
⽂件内容如下:代码如下:import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Map;public class HillCrypto {private Map<Character, Integer> table;private Map<Integer, Character> getPlainMap;private int[][] encryption = {{1, 1},{0, 3}};private int[][] decryption;public HillCrypto(String tableFilePath) {// TODO Auto-generated constructor stubint mrow = encryption.length;int mcolumn = encryption[0].length;this.decryption = new int[mrow][mcolumn];// ⼆阶矩阵的逆矩阵,如果是更⾼阶的,使⽤其他办法,⽐如通过余⼦式除以⾏列式得到逆矩阵,⾏列式的求法见鄙⼈的其他博客。
Hill 密码1. 原理介绍希尔密码(Hill Cipher)是运⽤基本矩阵论原理的代替密码技术,由 Lester S. Hill 在 1929 年发明,26 个英⽂字母可表⽰成 0 ~ 25 的数字,将明⽂转化成 n 维向量,与⼀个 n × n 矩阵相乘后,得到的结果模 26,即可得到密⽂对应的值假设对明⽂ act 加密:a 为 0,b 为 1,t 为 19,对其进⾏向量化得到 M =[0,2,19]T 。
选取 3 × 3 阶矩阵密钥:6241131610201715加密过程如下:6241131610201715×0219=67222319=15147mod 26得到的密⽂为 pob解密时,必须先算出密钥的逆矩阵,再根据加密的过程做逆运算2. 矩阵求逆对于矩阵求逆,常见的有 伴随矩阵 和 ⾏变换 两种⽅法,不过需要注意的是,此处的逆矩阵为模 26 的逆矩阵,也就是所⾥⾯所有的运算(加减乘除)都是在模 26 下的运算2.1 利⽤伴随矩阵⼀个 n ×n 矩阵 A ,A 的逆矩阵 A −1 为 1d ⋅(C A )T 。
其中 d 是矩阵 A 的⾏列式,C A 是 A 的伴随矩阵,(C A )T 是 C A 的转置矩阵在求伴随矩阵的转置 (C A )T 的过程中,只使⽤了乘法与加减法运算, 并未使⽤特殊的除法运算,故算法过程与对⼀般矩阵求 (C A )T ⽆异,区别只在于每次运算时都需要模 26在求矩阵⾏列式 d 的时候,若是采⽤余⼦式法,则也与⼀般矩阵⽆异。
最后使⽤ 扩展欧⼏⾥得 算法判断逆元的存在性:若不存在逆元,则矩阵在模 26 条件下不可逆;若存在逆元,则结合上述求解出的 (C A )T 可计算出 A −12.2 利⽤⾼斯⾏变换(1) 先不考虑模 26 的条件根据求伴随矩阵的过程,有 A −1=1d ⋅(C A )T ,那么 (C A )T =dA −1。
Hill 密码Hill 体制是1929年由Lester S.Hill 发明的,它实际上就是利用了我们熟知的线性变换方法,是在26Z 上进行的。
Hill 体制的基本思想是将n 个明文字母通过线性变换转化为n 个密文字母,解密时只需做一次逆变换即可,密钥就是变换矩阵。
设明文n n Z m m m m 2621),,(∈⋯+=,密文n n Z c c c c 2621),,.,(∈⋯=,密钥为26Z 上的n n ⨯阶可逆方阵n n ij k K ⨯=)(,则26mod 26mod 1-==cK m mK c 解密:明文加密:密文具体过程:1、 假设要加密的明文是由26个字母组成,其他字符省略。
2、 将每个字符与0-25的一个数字一一对应起来。
(例如:a/A —0,b/B —1,……z/Z —25)。
3、 选择一个加密矩阵n n A ⨯,其中矩阵A 必须是可逆矩阵,例如⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡=15227132102123916296101571823055117A 4、 将明文字母分别依照次序每n 个一组(如果最后一组不足n 个的话,就将其补成n个),依照字符与数字的对应关系得到明文矩阵ming n n len ⨯/。
5、 通过加密矩阵A ,利用矩阵乘法得到密文矩阵mi n n len ⨯/= ming n n len ⨯/⨯n n A ⨯mod 26;6、 将密文矩阵的数字与字符对应起来,得到密文。
7、 解密时利用加密矩阵的逆矩阵1-A 和密文,可得到明文。
实例 随机产生一个5阶加密方阵⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡=15227132102123916296101571823055117A得到方阵A 的逆矩阵⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡=-9131341212252318151920391211824723102141871A加密过程:输入明文:Hill cipher is one of my favorite cipher分组:Hillc ipher isone ofmyf avori tecip her(aa)加密得到密文:SKSXAQERQQYDVDGBKNVSMWZATGIAPDOJBIO解密过程:输入密文:SKSXAQERQQYDVDGBKNVSMWZATGIAPDOJBIO解密得到密文:HILLCIPHERISONEOFMYFA VORITECIPHERAA代码部分:#include <iostream>#include <string>#include <math.h>#include <stdlib.h>using namespace std;int A[1000][1000];//转化矩阵int a[1000][1000];//[A E]int B[1000][1000];//A^(-1)int ming[1000][1000];//明文矩阵int mi[1000][1000];//密文矩阵int n;//矩阵的阶数void input()//输入数据{int i, j;//cout << "请输入矩阵的元素" << endl;for( i = 1; i <= n; i++ )for( j = 1; j <= n; j++ )//cin >> A[i][j];A[i][j] = rand() % 26;memcpy( a, A, sizeof( A ) );//将矩阵A 复制给afor( i = 1; i <= n; i++ )//将矩阵变成[a E]的形式,E 为单位矩阵{for( j = n + 1; j <= 2*n; j++ ){if( i + n == j )a[i][j] = 1;elsea[i][j] = 0;}}}void output(){int i,j;cout << "矩阵阶数:" << n <<endl;cout << "矩阵A的元素:" << endl;for( i = 1; i <= n; i++ ){for( j = 1; j <= n; j++ )cout << A[i][j] << " ";cout << endl;}cout << "A矩阵的逆矩阵B为" << endl;for( i = 1; i <= n; i++ )//输出A矩阵的逆矩阵B{for( j = 1; j <= n; j++ ){B[i][j] = a[i][j+n];cout << B[i][j] << " ";}cout << endl;}}int Extend_Gcd( int a, int b, int &x, int &y )//扩展欧几里得算法{if( b == 0 ){x = 1;y = 0;return a;}int r = Extend_Gcd( b, a % b, x, y ); //a'=b;b'=a%b; a'x + b'y <=> bx + (a-a/b*b)y <=> ay + b(x-a/b*y)int t = x;x = y;y = t - a / b * y;return r;}int ni( int a)//求逆a*x=1(mod n){int x, y;int d = Extend_Gcd( a, 26, x, y );if( d == 1 )return ( x % 26 + 26 ) % 26;elsereturn -1;}int gaosi()//高斯-约当消元求A矩阵的逆矩阵B{int i, j, k;for( k = 1; k <= n; k++ )//高斯-约当消元{int Ni = ni( a[k][k] );if( Ni == -1 ) return 0;//cout << Ni << endl;for( i = k + 1; i <= 2 * n; i++ )a[k][i] = ( a[k][i] * Ni % 26 + 26 ) % 26;for( i = 1; i <= n; i++ ){if( i == k ) continue;for( j = k + 1; j <= 2 * n; j++ )a[i][j] = ( ( a[i][j] - a[i][k] * a[k][j] % 26 ) % 26 + 26 ) % 26;}}return 1;}void jiami() //加密过程{int i, j, k;char mingstr[100];char mingc;cout << "请输入明文" << endl;cin >> mingstr;//getchar();//gets( mingstr );int len = strlen( mingstr );if( len % n ){for( i = len; i < len/n*n+n; i++)mingstr[i] = 'a';mingstr[i] = '\0';}puts( mingstr );int Len = strlen( mingstr );cout << "字符串长度:" << Len << endl;for( i = 1; i <= Len/n; i++ )//将明文分成len/n段{for( j = 1; j <= n; j++ )//求每一段的明文转换为矩阵{if( mingstr[(i-1)*n+j-1] >= 'a' && mingstr[(i-1)*n+j-1] <= 'z' )ming[i][j] = mingstr[(i-1)*n+j-1] - 'a';elseming[i][j] = mingstr[(i-1)*n+j-1] - 'A';//cout << ming[i][j] << " ";}//cout << endl;}for( k = 1; k <= Len/n; k++ )//求len/n段的密文矩阵{for( i = 1; i <= n; i++ )//利用矩阵的乘法{mi[k][i] = 0;for( j = 1; j <= n; j++ )mi[k][i] = ( mi[k][i] + ming[k][j] * A[j][i] % 26 + 26 ) % 26;//cout << mi[k][i] << endl;}}cout << "密文为" << endl;for( i = 1; i <= Len/n; i++ )//输出密文{for( j = 1; j <= n; j++ ){mingc = mi[i][j] + 'A';cout << mingc;}}cout << endl;}void jiemi()//解密过程{int i, j, k;char mistr[100];char mingc;cout << "请输入密文" << endl;cin >> mistr;//getchar();//gets( mistr );//puts( mistr );int len = strlen( mistr );for( i = 1; i <= len/n; i++ )//将密文分成len/n段{for( j = 1; j <= n; j++ )//求每一段的密文转换为矩阵{if( mistr[(i-1)*n+j-1] >= 'a' && mistr[(i-1)*n+j-1] <= 'z' )mi[i][j] = mistr[(i-1)*n+j-1] - 'a';elsemi[i][j] = mistr[(i-1)*n+j-1] - 'A';}}for( k = 1; k <= len/n; k++ )//求len/n段的明文矩阵{for( i = 1; i <= n; i++ )//利用矩阵的乘法{ming[k][i] = 0;for( j = 1; j <= n; j++ )ming[k][i] = ( ming[k][i] + mi[k][j] * B[j][i] % 26 + 26 ) % 26;// cout << mi[i] << endl;}}cout << "明文为" << endl;for( i = 1; i <= len/n; i++ )//输出明文{for( j = 1; j <= n; j++ ){mingc = ming[i][j] + 'A';cout << mingc;}}cout << endl;}int main(){bool flag = 1;cout << "欢迎使用Hill体制进行加解密!" << endl;while( flag ){cout << "请输入加密矩阵的阶数n:";cin >> n;do{input();//数据输入}while( !gaosi() );output();//gaosi();//用高斯-约当消元求矩阵A%26的逆Bjiami();//加密过程jiemi();//解密过程cout << "是否继续加密解密?1:继续,0:否" << endl;cin >> flag;}return 0;}/*abcdefghijklmnopqrstuvwxyz*/。
【实验十】Hill密码的加密、解密与破译一、实验目的本实验主要涉及代数,利用模运算下的矩阵乘法、求逆矩阵、线性无关、线性空间与线性变换等概念和运算,学习Hill密码体制的加密、解密和破译过程二、实验任务任务五找出元素属于Z26的所有可能的Hill2密码加密矩阵。
若截获了如下一段密文:UTCQCVFOYQUVMGMGULFOLEYHDUHOPEASWXTIFBAMWT且已知它是根据表10.1按Hill2密码体制加密的,你能否将其解密?分析:对于第一问,找出元素属于Z26的所有可能的Hill2密码加密矩阵,我们只需要用枚举法即可。
关键在于第二问的解密,根据我们编写的C++程序,共有约15万个可能的加密矩阵,也就对应着同等数量的可能明文。
所以问题的重点就在于如何从这么多数量的明文中筛选出有意义的信息。
1、找出元素属于Z26的所有可能的Hill2密码加密矩阵C++源代码(枚举加密矩阵部分):chain_mat* head=new chain_mat; //加密矩阵用链表储存head->next=NULL;chain_mat* now=head;int n=0;for(int a=0;a<26;a++)for(int b=0;b<26;b++)for(int c=0;c<26;c++)for(int d=0;d<26;d++){intdet=a*d-b*c;if(det%2!=0&&det%13!=0) //判断是否模26可逆{chain_mat* newm=new chain_mat;newm->dat[0][0]=a;newm->dat[0][1]=b;newm->dat[1][0]=c;newm->dat[1][1]=d;n++; //累加符合要求的矩阵数量now->next=newm;now=now->next;now->next=NULL;}}运行结果:n=157248由于矩阵数量过多,我们将其存储在matrixlist.txt文件中C++源代码(输出矩阵部分):voidoutput_mat(chain_mat* head){ofstreamoutfile;outfile.open("matrixlist.txt");chain_mat* now=head->next;while(now!=NULL){outfile<<now->dat[0][0]<<'\t'<<now->dat[0][1]<<'\n'<<now->dat [1][0]<<'\t'<<now->dat[1][1]<<"\n=========="<<endl;now=now->next;}outfile.close();}下面给出matrixlist.txt中部分内容(完整文件将发至邮箱):0 11 0==========0 11 1==========0 11 2==========0 11 3==========0 11 4==========0 11 5==========0 11 6==========0 11 7==========0 11 8==========0 11 9==========0 11 10==========2.解密题中密文首先需要做的是对矩阵进行模逆运算C++源代码(模26逆矩阵运算部分):voidinv(chain_mat* m1){intdet=m1->dat[0][0]*m1->dat[1][1]-m1->dat[0][1]*m1->dat[1][0];det=reci(det);inttmp;tmp=m1->dat[0][0]*det;m1->dat[0][0]=m1->dat[1][1]*det;m1->dat[1][ 1]=tmp;m1->dat[0][1]*=-1*det;m1->dat[1][0]*=-1*det;for(inti=0;i<2;i++)for(int j=0;j<2;j++){m1->dat[i][j]%=26;if(m1->dat[i][j]<0)m1->dat[i][j]+=26;}}然后用逆矩阵乘密文向量,得到可能明文序列,存入名为me1的string数组中C++源代码(模26逆矩阵运算部分):n=0;while(now!=NULL)inv(now);for(inti=0;i<sizeof(str)-1;i+=2){int s1=now->dat[0][0]*co1[i]+now->dat[0][1]*co1[i+1];int s2=now->dat[1][0]*co1[i]+now->dat[1][1]*co1[i+1];s1%=26;s2%=26;if(s1<0)s1+=26;if(s2<0)s2+=26;if(s1==0)s1=26;if(s2==0)s2=26;me1[n]+=('A'+s1-1);me1[n]+=('A'+s2-1);}n++;inv(now);now=now->next;}至此,我们得到了157248条可能的明文,接下来就要考虑筛选的问题。
Hill 密码的加密、解密与破译[实验十] Hill 密码的加密、解密与破译一、实验目的本实验主要涉及代数,利用模运算意义下的矩阵乘法、求逆矩阵、线性无关、线性空间与线性变换等概念和运算,学习Hill 密码体制的加密、解密和破译过程。
二、实验内容(1)甲方收到与之有秘密通信往来的乙方的一个密文信息,密文内容: W O W U Y S B A C P G Z S A V C O V K P E W C P A D K P P A B U J C Q L Y X Q E Z A A C P P按照甲方与乙方的约定,他们之间的密文通信采用Hill 2密码,密钥为二阶矩阵 且汉语拼音的26个字母与0~25之间的整数建立一一对应的关系,称之为字母的表值,具体的表值见表10. 1 明文字母的表值。
问这段密文的原文是什么?(2)甲方截获了一段密文: O J W P I S W A Z U X A U U I S E A B A U CR S I P L B H A A M M L P J J O T E N H 经分析这段密文是用Hill 2密码编译的,且这段密文的字母UCRS 依次代表字母TACO ,问能否破译这段密文的内容?三、Hill 2密码的数学模型 Ⅰ、加密与解密过程Hill 2密码是一种传统的密码体制,它的加密过程可用以下框图描述:⎪⎭⎫⎝⎛=3021A明文------加密器------密文------普通信道------解密器密码分析(敌方截获)----- 明文在这个过程中,运用的数学手段是矩阵运算,加密过程的具体步骤如下: 1.根据明文字母的表值将明文信息用数字表示,设明文信息只需要26个拼音字母A~Z (也可能不止26个,如还有数字、标点符号等),通信双方给出这26个字母表值(见表10.1明文字母的表值)。
2.选择一个二阶可逆整数方阵A ,称为Hill 2密码的加密矩阵,它是这个加密体制的“密钥”(是加密的关键,仅通讯双方掌握)。