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 }