四种古典密码的C++实现(3)-----Playfair密码

  1 //Playfair密码
  2 /*理解算法最重要,最好自己动手实现试试看,可以使用MFC写一个简单的交互界面*/
  3 #include<iostream>
  4 #include<cstring>
  5 
  6 using namespace std;
  7 void encrypt()
  8 {
  9     const int N=100;
 10     char letters[26]="ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
 11     int flag[25]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//字母是否已在矩阵中,与letters数组对应
 12     char ch[5][5];//5X5矩阵
 13     char ch1[N];//密钥
 14     char ch2[N];//明文
 15     char ch4;//无关字符
 16     int len='a'-'A';
 17     cout<<"输入密钥:";
 18     cin>>ch1;
 19     int flg=1;
 20     while(flg==1)
 21     {
 22         for(int i=0;i<strlen(ch1);i++)//把所输入的密钥转化为大写字母
 23         {
 24             if(ch1[i]>'z'||ch1[i]<'a')
 25             {
 26                 cout<<"请重新选择操作:"<<endl; 
 27                 flg=0;break;
 28             }
 29             else
 30                 ch1[i]=ch1[i]-len;
 31         }
 32         if(flg==1)
 33         {    for(int i=0;i<strlen(ch1);i++)//把密钥中的J都变为I
 34         {
 35             if(ch1[i]=='J')ch1[i]='I';
 36         }
 37         int i=0;int j=0; 
 38 //把密钥中的字母填入到矩阵中,并把该字母标记为已用
 39         for(int k=0;k<strlen(ch1);k++) 
 40         {
 41             for(int t=0;t<25;t++)
 42             {
 43                 if(ch1[k]==letters[t]&&flag[t]==0)
 44                 {
 45                     ch[i][j]=letters[t];
 46                     flag[t]=1;
 47                     if(j<4)j++;
 48                     else {i++;j=0;}
 49                 }
 50             }
 51         }
 52         for( int k=0;k<25;k++)//按字母表顺序把未用字母依次填入到矩阵中
 53         {
 54             if(flag[k]==0)
 55             {
 56                 ch[i][j]=letters[k];
 57                 flag[k]=1;
 58                 if(j<4)j++;
 59                 else{i++;j=0;}
 60             }
 61         }
 62         cout<<"密钥填充后的矩阵为: "<<endl;
 63         for(i=0;i<5;i++)
 64           for(j=0;j<5;j++)
 65             {
 66                 cout<<ch[i][j];
 67                 cout<<" ";
 68                 if(j==4) 
 69                     cout<<endl;
 70             }
 71             cout<<endl;
 72             cout<<"请输入明文(请输入英文字符):";
 73             cin>>ch2;
 74             cout<<"输入一个无关字符:";
 75             cin>>ch4;
 76             if(ch4>='a')
 77                 ch4=ch4-len;
 78             for(int k=0;k<strlen(ch2);k++)//把所输入的明文转化为大写字母
 79             {
 80                 if(ch2[k]>='a')
 81                     ch2[k]=ch2[k]-len;
 82             }
 83             for(int k=0;k<strlen(ch2);k++)//把明文中的J都变为I
 84             {
 85                 if(ch2[k]=='J')
 86                     ch2[k]='I';
 87             }
 88 //为明文添加必要的无关字符以防止同一组的两个字符相同
 89             for( int k=0;k<strlen(ch2);k+=2) 
 90             {
 91                 if(ch2[k]==ch2[k+1])
 92                 {
 93                     for(int t=strlen(ch2);t>k;t--)
 94                         ch2[t+1]=ch2[t];
 95                     ch2[k+1]=ch4;
 96                 }
 97             }
 98 //若明文有奇数个字符,则添加一个无关字符以凑够偶数个
 99             if(strlen(ch2)%2!=0) 
100             {
101                 ch2[strlen(ch2)+1]=ch2[strlen(ch2)];//字符串结尾赋'\0'
102                 ch2[strlen(ch2)]=ch4;//明文串尾插入无关字符
103             }
104             cout<<"经过处理后的明文为:";
105             for(int k=0;k<strlen(ch2);k+=2)
106                 cout<<ch2[k]<<ch2[k+1]<<" ";
107             cout<<endl;
108             cout<<"其最终长度为:"<<strlen(ch2)<<endl;
109             //////////////////明文输入并整理完毕///////////////////////////////
110             for(int k=0;k<strlen(ch2);k+=2)
111             {
112                 int m1,m2,n1,n2;
113                 for(m1=0;m1<=4;m1++)
114                 {for(n1=0;n1<=4;n1++)
115                 {
116                     if(ch2[k]==ch[m1][n1])break;
117                 }
118                 if(ch2[k]==ch[m1][n1])break;
119                 }
120                 for(m2=0;m2<=4;m2++)
121                 {
122                     for(n2=0;n2<=4;n2++)
123                     {
124                         if(ch2[k+1]==ch[m2][n2])break;
125                     }
126                     if(ch2[k+1]==ch[m2][n2])break;
127                 }
128                 m1=m1%5;
129                 m2=m2%5;
130                 if(n1>4){n1=n1%5;m1=m1+1;}
131                 if(n2>4){n2=n2%5;m2=m2+1;}
132                 if(m1==m2)
133                 {
134                     ch2[k]=ch[m1][(n1+1)%5];
135                     ch2[k+1]=ch[m2][(n2+1)%5];
136                 }
137                 else 
138                 {
139                     if(n1==n2)
140                     {
141                         ch2[k]=ch[(m1+1)%5][n1];
142                         ch2[k+1]=ch[(m2+1)%5][n2];
143                     }
144                     else
145                     {ch2[k]=ch[m1][n2];
146                     ch2[k+1]=ch[m2][n1];
147                     }
148                 }
149             }
150             cout<<"加密后所得到的密文是:";
151             for(int k=0;k<strlen(ch2);k+=2)
152                 cout<<ch2[k]<<ch2[k+1]<<" ";
153             cout<<endl;
154         }else break;
155         }
156         
157 }
158 
159 //解密算法
160 void decrypt()
161 {
162     const int N=100;
163     char letters[26]="ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
164     int flag[25]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
165     //标记字母是否已在矩阵中,与letters数组对应
166     char ch[5][5];//5X5矩阵
167     char ch1[N];//密钥
168     char ch2[N];//密文
169     int len='a'-'A';
170     int flg=1;
171     cout<<"输入密钥:";
172     cin>>ch1;
173     while(flg==1)
174     {
175         for(int i=0;i<strlen(ch1);i++)//把所输入的密钥转化为大写字母
176         {if(ch1[i]>'z'||ch1[i]<'a')
177         {
178             cout<<"请重新选择操作:"<<endl; 
179             flg=0;break;
180         }
181         else
182             ch1[i]=ch1[i]-len;
183         }
184         if(flg==1)
185         {    for(int i=0;i<strlen(ch1);i++)//把密钥中的J都变为I        
186 {
187             if(ch1[i]=='J')ch1[i]='I';
188         }
189         int i=0;int j=0;
190         //把密钥中的字母填入到矩阵中,并把该字母标记为已用
191 for(int k=0;k<strlen(ch1);k++) 
192         {
193             for( int t=0;t<25;t++)
194             {
195                 if(ch1[k]==letters[t]&&flag[t]==0)
196                 {
197                     ch[i][j]=letters[t];
198                     flag[t]=1;
199                     if(j<4)j++;
200                     else {i++;j=0;}
201                 }
202             }
203         }
204         for( int k=0;k<25;k++)//按字母表顺序把未用字母依次填入到矩阵中
205         {
206             if(flag[k]==0)
207             {
208                 ch[i][j]=letters[k];
209                 flag[k]=1;
210                 if(j<4)j++;
211                 else{i++;j=0;}
212             }
213         }
214         cout<<"密钥填充后的矩阵为: "<<endl;
215         for(i=0;i<5;i++)
216             
217             for(j=0;j<5;j++)
218             {
219                 cout<<ch[i][j];
220                 cout<<" ";
221                 if(j==4) 
222                     cout<<endl;
223             }
224             cout<<endl;
225             /////////////////////矩阵生成完毕////////////////////////////
226             int f=0;
227             do{
228                 cout<<"请输入密文(英文字符):";
229                 cin>>ch2;
230                 for(int k=0;k<strlen(ch2);k++)//把所输入的密文转化为大写字母
231                 {
232                     if(ch2[k]>='a')
233                         ch2[k]=ch2[k]-len;
234                 }
235                 for( int k=0;k<strlen(ch2);k++)//把密文中的J都变为I
236                 {
237                     if(ch2[k]=='J')ch2[k]='I';
238                 }
239                 for( int k=0;k<strlen(ch2);k+=2)
240                 {
241                     if(ch2[k]==ch2[k+1])
242                     {
243                         cout<<"同一分组中不能出现相同字符!请重新输入。"<<endl;
244                         f=1;
245                         break;
246                     }else f=2;
247                 }
248                 if(f==1)continue;
249                 if(strlen(ch2)%2!=0)
250                 {
251                     cout<<"字符串不能为奇数个!请重新输入。"<<endl;
252                     f=1;
253                 }
254                 else f=2;
255             }while(f==1);
256             //解密开始
257             for( int k=0;k<strlen(ch2);k+=2)
258             {
259                 int m1,m2,n1,n2;
260                 for(m1=0;m1<=4;m1++)
261                 {
262                     for(n1=0;n1<=4;n1++)
263                     {
264                         if(ch2[k]==ch[m1][n1])break;
265                     }
266                     if(ch2[k]==ch[m1][n1])break;
267                 }
268                 for(m2=0;m2<=4;m2++)
269                 {
270                     for(n2=0;n2<=4;n2++)
271                     {
272                         if(ch2[k+1]==ch[m2][n2])break;
273                     }
274                     if(ch2[k+1]==ch[m2][n2])break;
275                 }
276                 m1=m1%5;
277                 m2=m2%5;
278                 if(n1>4){n1=n1%5;m1=m1+1;}
279                 if(n2>4){n2=n2%5;m2=m2+1;}
280                 if(m1==m2)
281                 {ch2[k]=ch[m1][(n1+4)%5];
282                 ch2[k+1]=ch[m2][(n2+4)%5];
283                 }
284                 else 
285                 {
286                     if(n1==n2)
287                     {
288                         ch2[k]=ch[(m1+4)%5][n1];
289                         ch2[k+1]=ch[(m2+4)%5][n2];
290                     }
291                     else
292                     {
293                         ch2[k]=ch[m1][n2];
294                         ch2[k+1]=ch[m2][n1];
295                     }
296                 }
297             }
298             cout<<"解密后所得到的明文是:";
299             for(int k=0;k<strlen(ch2);k+=2)
300                 cout<<ch2[k]<<ch2[k+1]<<" ";
301             cout<<endl;
302       }
303       else break;
304         }
305         
306 }
307 
308 int main()
309 {  
310 
311     int n;
312     cout<<"请选择1加密2解密:"<<endl;
313     while(true)
314     {
315         cin>>n;
316         switch(n)
317         {
318         case 1:
319             encrypt();
320             break;
321         case 2:
322             decrypt();
323             break;
324             default:
325                 break;    
326         }
327     }
328     return 0;    
329 }

 

posted @ 2017-04-12 19:48  nanashi  阅读(831)  评论(0编辑  收藏  举报