利用playfair置换实现密钥加密
2015-08-01 12:22
441 查看
北航15年机试题2:
(仅靠回忆,可能描述不太明确)
给定一个密钥key,利用playfair加密算法进行加密
首先根据密钥生成置换矩阵(5*5),对于26个英文字母,将不在密钥中的字母按顺序依次写入到矩阵中,其中必定有一个字母是不在矩阵中的。将对角线字母进行置换,如dc置换为ag.
如密钥key: youandme
则置换矩阵为:
b | c | f | g | h |
i | j | k | l | p |
q | r | s | t | v |
w | x | z | y | o |
u | a | n | d | m |
1)如果两个字母完全相同,则不进行置换,直接将原字母输出
2)如果其中有一个字母不在字母表中,则不进行置换,直接输出
3)如果最后只剩一个字母,则将其直接输出
4)如果两个字母在同一行或者同一列,直接交换两字母的顺序后输出
5)如果两个字母不在同一行且不在同一列,则按照矩阵进行置换,如cd置换为ga
输入样例:
首先输入密钥youandme
然后先输入要加密的数据welcometohangzhou
然后输出加密后的数据 wejgmoethonayfohu (我自己根据规则置换的,正确的结果不记得了)
提示:最好按照给定的规则顺序进行判断并进行加密(具体的规则以及规则的顺序我也记不太清楚……)思路:
比较简单,关键就是形成加密的置换矩阵,考虑了密钥中可能含有重复字母的情况,要删去密钥中重复的字母
#include <stdio.h> #include <string.h> char c[5][5]; char key[30]; int x=-1,y=-1; int findpos(char t){ // 实现寻找明文字符在置换矩阵中的位置,如果在矩阵中,则返回1并将索引位置保存在x,y中;如果不在矩阵中,则返回-1 int i,j; for(i=0;i<5;i++){ for(j=0;j<5;j++) if(c[i][j]==t){ x=i; y=j; return 1; } } return -1; } void delrepeat(){ int i,j; int len=strlen(key); for(i=0;i<len;i++){ for(j=i+1;j<len;j++){ if(key[i]==key[j]) key[j]='*'; } }//将重复的字符置为'*' //以下代码删除重复的字符 for(i=0;i<(int)strlen(key);i++){ if(key[i]=='*'){ for(j=i;j<len-1;j++) key[j]=key[j+1]; key[j]='\0'; i--;//此处语句是为了删除相邻重复字符 } } } int main(){ char plain[50]; scanf("%s\n",key); scanf("%s",plain); char abc[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; int i,j; int keylen=strlen(key); printf("%d %s\n",keylen,key); for(i=0;i<26;i++){ for(j=0;j<keylen;j++){ if(abc[i]==key[j]) abc[i]='*'; } } int k=0; for(i=0;i<5&&k<26;i++){ for(j=0;j<5&&k<26;j++){ if(abc[k]=='*'){ k++; j--; } else{ c[i][j]=abc[k]; k++; } } } delrepeat(); k=0; i--; for(;i<5;i++){ for(;j<5;j++){ c[i][j]=key[k++]; } j=0; //机试时此处出现了错误,忘加这条语句导致矩阵最后一行没能正常生成 } //以上代码形成置换矩阵,以下代码按照规则进行置换加密 int plainlen=strlen(plain); for(i=0;i<plainlen-1;i+=2){ int t1=plain[i]; int t2=plain[i+1]; if(t1==t2) printf("%c%c",t1,t2); int is1=findpos(t1); int t1x=x; int t1y=y; int is2=findpos(t2); int t2x=x; int t2y=y; if(is1==-1||is2==-1) printf("%c%c",t1,t2); else if(t1x==t2x||t1y==t2y) printf("%c%c",t2,t1); else printf("%c%c",c[t1x][t2y],c[t2x][t1y]); } if(i==plainlen-1) //加密的明文只剩最后一个字母 printf("%c\n",plain[i]); return 0; }
相关文章推荐
- 安装 rails 失败
- Exception from container-launch: org.apache.hadoop.util.Shell$ExitCodeException
- HDU-5319 Painter
- EAGAIN、EWOULDBLOCK、EINTR与非阻塞 长连接
- hdu 1151 Air Raid(最小路径覆盖)
- 获得手势所在的图片坐标 & CGRectContainsPoint
- hdu 5335 Walk Out(bfs+斜行递推) 2015 Multi-University Training Contest 4
- 2015 Multi-University Training Contest 2
- hdu2473 Junk-Mail Filter
- 基础知识:开漏(open drain)和开集(open collector)
- 可视化存储智能解决方案之一“大话Raid2.0”
- Submission Details
- Xcode failed to get reply to handshake packet
- rails 学习第一天笔记
- hd1789 Doing Homework again
- Aircrack-ng支持网卡列表(下)
- Convolutional Neural Networks at Constrained Time Cost(精读)
- 1022:Train Problem I
- Visualization of Detail Point Set by Local Algebraic Sphere Fitting
- Visual Studio 2008 Package Load Failure:未能正确加载包“Microsoft.VisualStudio.Xaml”