admin 管理员组

文章数量: 887006

实现playfair(多字母替代密码)加密与解密程序

   Playfair密码(英文:Playfair cipher 或 Playfair square)是一种替换密码,1854年由查尔斯·惠斯通(Charles Wheatstone)的英国人发明。经莱昂·普莱费尔提倡在英国军地和政府使用。    它有一些不太明显的特征:密文的字母数一定是偶数;任意两个同组的字母都不会相同,如果出现这种字符必是乱码和虚码。    它使用方便而且可以让频度分析法变成瞎子,在1854到1855年的克里米亚战争和1899年的布尔战争中有广泛应用。但在1915年的一战中被破译了。 

  编写分三步:1.编制密码表 2.整理明文 3.编写密文 构成部分:1.密钥 2.明文3.密文4.注明的某个字母代替的另一个字母

 

代码实现:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>char playfair_table[5][5];
void CreateTable (char *in_key)
{int i = 0, j, k;int hash[26]={0};char key[26] = {0};int key_len;strcpy (key, in_key);key_len = strlen (key);//一次遍历,处理密钥while (1){if (i == key_len)break;//转换成大写if(key[i]>='a'&&key[i]<='z'){key[i]+='A'-'a';}//去除非法字符if (!(key[i]<='Z'&&key[i]>='A')){for (j = i; j < key_len - 1; ++j)key[j] = key[j + 1];key_len--;continue;}if(key[i]=='J'){//I和J视为相同key[i]='I';}if(hash[key[i]-'A']==0){hash[key[i]-'A']=1;}else //去除重复{for (j = i; j < key_len - 1; ++j)key[j] = key[j + 1];key_len--;continue;}i++;}//此时,密钥长度必然小于26,长度不够需补全if(key_len<25){for(i=0;i<26;i++){if(key_len==25){break;}if(i+'A'=='J')continue;if(hash[i]==0){hash[i]=1;key[key_len]=i+'A';key_len++;}}}for (i = 0; i < 5;i++){for (j = 0; j < 5; j++)playfair_table[i][j] = key[5 * i + j];}
}void PrintTable ()
{int i, j;printf ("Playfair Table:\n");for (i = 0; i < 5; ++i){printf ("\t");for (j = 0; j < 5; ++j){printf ("%c ", playfair_table[i][j]);}puts("\n");}}void GetPosition (char c, int *x, int *y)
{int i, j;if(c>='a'){c+=-'a'+'A';}for (i = 0; i < 5; ++i){for (j = 0; j < 5; ++j){if (playfair_table[i][j] == c){*x = i; *y = j;return;}}}
}char GetKey (int x, int y,char type)
{if (x < 0)x += 5;if (y < 0)y += 5;if(type<'a'){return playfair_table[x % 5][y % 5];}else{return (playfair_table[x % 5][y % 5]+'a'-'A');}
}int Encrypt (char *input, char *output)
{int length = strlen (input);int i = 0, j=-1,find;int ax, ay, bx, by;int pair[2]={-1,-1};//for(i=0;i<length;i++)//{//	if(input[i]>='A'&&input[i]<='Z')//	{//		input[i]-='A'-'a';//全部转化成小写//	}//}while(1){char between[1000]={0};int betweenlength=-1;find=0;//找寻成对出现的第一个字符所在位置for(i=pair[1]+1;i<length;i++){if((input[i]>='a'&&input[i]<='z')||(input[i]>='A'&&input[i]<='Z')){pair[0]=i;pair[1]=i+1;find=1;break;}else{output[++j]=input[i];}}if(find==0){break;}//找寻成对出现的第二个字符所在位置find=0;for(i=pair[1];i<length;i++){if((input[i]>='a'&&input[i]<='z')||(input[i]>='A'&&input[i]<='Z')){pair[1]=i;find=1;break;}else{between[++betweenlength]=input[i];}}if(find==0){input[length]='Q';//代表最后一位的填充pair[1]=length;length++;}//开始加密过程if(input[pair[1]]==input[pair[0]]){if(input[pair[0]]!='X')//放置连续的xx影响结果{//属于相同对中的重复的明文字母将用一个填充字母进行分隔(如x)   for(i=length;i>=pair[1];i--){input[i+1]=input[i];}length++;input[pair[1]]='X';}}GetPosition(input[pair[0]],&ax,&ay);GetPosition(input[pair[1]],&bx,&by);//若p1 p2在同一行,对应密文c1 c2分别是紧靠p1 p2 右端的字母。其中第一列被看做是最后一列的右方。if(ax==bx){output[++j]=GetKey(ax,ay+1,input[pair[0]]);for(i=0;i<=betweenlength;i++){output[++j]=between[i];}output[++j]=GetKey(bx,by+1,input[pair[1]]);}//若p1 p2在同一列,对应密文c1 c2分别是紧靠p1 p2 下方的字母。其中第一行被看做是最后一行的下方。 else if(ay==by){output[++j]=GetKey(ax+1,ay,input[pair[0]]);for(i=0;i<=betweenlength;i++){output[++j]=between[i];}output[++j]=GetKey(bx+1,by,input[pair[1]]);}//若p1 p2不在同一行,不在同一列,则c1 c2是由p1 p2确定的矩形的其他两角的字母,并且c1和p1, c2和p2同行。 else{output[++j]=GetKey(ax,by,input[pair[0]]);for(i=0;i<=betweenlength;i++){output[++j]=between[i];}output[++j]=GetKey(bx,ay,input[pair[1]]);}}return length;
}int Decry

本文标签: 实现playfair(多字母替代密码)加密与解密程序