Playfair 加密
题目真的好长但是意思很简单
89.加密 (15分)
C时间限制:3 毫秒 | C内存限制:3000 Kb
题目内容:
一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中
其他字母一起填入至一个5x5的方阵中,填入方法如下:
1.首先按行填入密钥串。
2.紧接其后,按字母序按行填入不在密钥串中的字母。
3.由于方阵中只有25个位置,最后剩下的那个字母则不需变换。
如果密钥为youandme,则该方阵如下:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
在加密一对字母时,如am,在方阵中找到以这两个字母为顶点的矩形:
o u a
m e b这对字母的加密字母为该矩形的另一对顶点,如本例中为ob。
请设计程序,使用上述方法对输入串进行加密,并输出加密后的串。
另外有如下规定:
1、一对一对取字母,如果最后只剩下一个字母,则不变换,直接放入加密串中;
2、如果一对字母中的两个字母相同,则不变换,直接放入加密串中;
3、如果一对字母中有一个字母不在正方形中,则不变换,直接放入加密串中;
4、如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母,即变换为fd或ih;
5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前
面,在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
6、本程序中输入串均为小写字母,并不含标点、空格或其它字符。
解密方法与加密相同,即对加密后的字符串再加密,将得到原始串。
输入描述
从控制台输入两行字符串,第一行为密钥单词(长度小于等于25,字母不重复,且都为小写字母),第二行为待加密字符串(长度
小于等于50),两行字符串末尾都有一个回车换行符,并且两行字符串均为小写字母,不含其它字符。输出描述
在标准输出上输出加密后的字符串。输入样例
youandme
welcometohangzhou输出样例
vbrmmomvugnagzguu
样例解释:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
welcometohangzhou
(一对一对找)找到对应的矩阵,输出另一个对角上面的字母,
如果其中一个字母不在矩阵中,原样输出
如果在同行或者同列,位置对调
如果剩最后一个字母,原样输出
we --> vb lc-->rm om -->mo et-->mv oh-->ug an-->na gz-->gz ho-->gu u-->u
#include <stdio.h> #include <string.h> char s1[26]; char str[55]; char s[5][5]; //加密矩阵 int a[27]; typedef struct{ int x, y; //记录字母的横纵坐标 }P; P p[27]; int main(){ scanf("%s%s", s1, str); memset(a, 0, sizeof a); int i = 0; while(s1[i]){ int d = s1[i] - 'a'; a[d] = 1; i++; } int k = 0, len = strlen(s1); int f = 0; for(int i = 0; i < 5; i++){ for(int j = 0; j < 5; j++){ if(k < len){ s[i][j] = s1[k]; k++; }else{ while(a[f] && f <= 25){ //循环结束时 a[f] = 0 f++; } char c = f + 'a'; s[i][j] = c; f++; } } } memset(a, 0, sizeof a); for(int i = 0; i < 5; i++){ for(int j = 0; j < 5; j++){ int d = s[i][j] - 'a'; p[d].x = i; p[d].y = j; a[d] = 1;//判断是否出现过 } } i = 0; len = strlen(str); while(str[i]){ if(i == len - 1){//最后一个单着 printf("%c", str[i]); i++; }else{ //找到横纵坐标 int d1 = str[i] - 'a'; int d2 = str[i+1] - 'a'; if(a[d1] && a[d2]){//就是都在加密矩阵中 int x1 = p[d1].x, y1 = p[d1].y; int x2 = p[d2].x, y2 = p[d2].y; //如果在同一列 if(y1 == y2){ printf("%c%c", str[i+1], str[i]); } else{ printf("%c%c", s[x1][y2], s[x2][y1]); } }else{ printf("%c%c", str[i], str[i+1]); } i += 2; } } return 0; }