Hill 加密算法
来源:互联网 发布:石油进口数据 编辑:程序博客网 时间:2024/05/21 17:59
Hill 密码简介
Hill 密码是一种多字母代替密码。
Hill 密码要求首先将明文分成同等规模的若干个分组(最后一个分组不足时需要填充),每一个分组被整体加密变换,即 Hill 密码属于分组加密。
Hill 密码算法的基本思想
将每一个分组中的 d 个连续的明文字母通过线性变换(与密钥矩阵相乘),转换为 d个密文字母。
- 明文:
m=m1m2…md - 密文:
c=c1c2…cd
其中,
c1=k11m1+k21m2+…+kd1md(mod26) c2=k12m1+k22m2+…+kd2md(mod26) ⋯ cd=k1dm1+k2dm2+…+kddmd(mod26)
写成矩阵形式:
(c1,c2,⋯cd)=(m1,m2,⋯md)⋅⎡⎣⎢⎢k11⋮kd1k12⋮kd2⋯⋱⋯k1dkdd⎤⎦⎥⎥(mod26)
即:密文分组 = 明文分组 X 密钥分组。
例:
用 Hill 密码加密明文 “Pay more money”,密钥是:
解:
明文 “Pay more money” 可编码为 15 0 24 12 14 17 4 12 14 13 4 24;(共4组)
计算:
故对应的密文为:RRLMWBKASPDH。
具体实现
#include <iostream>#include <cstring>#include <cstdlib>#define N 100using namespace std;//按第一列展开,递归计算行列式值 int caluDet(int n, int **a){ int i, r, c, p, q; int sum=0; if(n==1) return a[0][0]; int **det = (int**)malloc((n-1)*sizeof(int*)); for(i=0; i<(n-1); i++) det[i] = (int*)malloc((n-1)*sizeof(int)); for(i=0; i<n; i++) { for(r=0; r<n-1; r++) { //子矩阵 (n-1) 行 if(r<i) p = 0; //当前行 a[r] 赋值给子矩阵 else p = 1; //下一行 a[r+1] 赋值给子矩阵 for(c=0; c<n-1; c++) //子矩阵 (n-1) 列 det[r][c] = a[r+p][c+1]; } if(i%2==0) q = 1; //由于是对第一列展开,即 [i][0] else q = -1; sum = sum + a[i][0] * q*caluDet(n-1,det); } for(i=0; i<(n-1); i++) free(det[i]); free(det); return sum;}//初始化明文void initPlain(char p[], int n){ int i, len, t; cout << "输入明文p: \n"; getchar(); gets(p); for(i=0; i<strlen(p); i++) { if (p[i] ==' ') //跳过空格 strcpy(p+i,p+i+1); if (p[i]>='a' && p[i]<='z') //小写转大写 p[i] -= 32; } len = strlen(p); t = len%n>0 ? n-len%n : len%n; while(t--) //若最后一个明文对字母不足,则添加与最后一个明文相同的字母 p[strlen(p)] = p[len-1]; p[strlen(p)] = '\0'; cout <<"\nInit P: " << p << endl; }//输入密钥矩阵void keyMatrix(int **det, int len){ int i, j; for(i=0; i<len; i++) for(j=0; j<len; j++) cin >> det[i][j]; }//分组、矩阵乘法void matricMultiply(char p[], char c[], int **key, int n) { int i,j,k; int len = strlen(p); for(i=0; i<strlen(p)/n; i++){ //明文每 n 个作为一行 for(j=0; j<n; j++){ //明文的列、密钥矩阵的列 for(k=0; k<n; k++){ //密钥矩阵的行 c[n*i+j] += ((p[n*i+k]-'A') * key[k][j]) % 26; } c[n*i+j] = c[n*i+j] % 26 + 'A'; //cout << (int)c[n*i+j] << " "; } } cout << "Cipher: " << c << endl; }int main(){ int i, j, n, len; char p[N]={0}, c[N]={0}; cout << "输入密钥的阶:\n"; cin >> n; //为密钥矩阵申请内存空间 int **key = (int**)malloc(n*sizeof(int*)); for(i=0; i<n; i++) key[i] = (int*)malloc(n*sizeof(int)); //获取密钥矩阵并验证是否可逆 cout << "输入" <<n<<"阶密钥矩阵:\n"; keyMatrix(key,n); while(!caluDet(n, key)) { cout << "密钥不存在逆矩阵! 请重新输入:\n"; keyMatrix(key,n); } //初始化明文 initPlain(p, n); len = strlen(p); //各组明文乘密钥矩阵加密 matricMultiply (p, c, key, n); //释放密钥矩阵的内存空间 for(i=0; i<n; i++) free(key[i]); free(key); return 0;}
测试结果
1 0
- Hill 加密算法
- 古典密码(Hill加密算法)
- HILL加密算法的C语言实现
- 跪求代码------hill加密算法在位图中的应用
- Craigie Hill
- VC Dimension && Hill Climbing
- Jeffery C. Hill
- python Hill密码
- hdu4315 Climbing the Hill
- Vigenere密码 Hill密码
- hill descent algorithm
- hdu4315Climbing the Hill
- 密码学之hill密码
- 加密算法
- 加密算法
- 加密算法
- 加密算法
- 加密算法
- centos安装jdk、tomcat、mysql环境
- 设计模式之享元模式
- spring-boot整合mybatis
- My First RPG Game总结三
- [leetCode刷题笔记]77. Combinations
- Hill 加密算法
- 11步教你入门webservice
- Matlab研究小问题:如何计算一条线段所经过的网格区域和各区域内的长度
- redis常用的几种数据类型介绍
- python num
- redis常用命令(基础篇)
- 001-开始golang开发之旅
- redis常用命令(高级篇)
- javah 错误: 找不到 'XX' 的类文件或Exception in thread "main" name: XX.class