您的位置:首页 > 大数据 > 人工智能

利用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: