您的位置:首页 > 编程语言 > C语言/C++

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

2017-10-25 09:08 519 查看
//Playfair密码
/*理解算法最重要,最好自己动手实现试试看,可以使用MFC写一个简单的交互界面*/
#include<iostream>
#include<cstring>

using namespace std;
void encrypt()
{
const int N=100;
char letters[26]="ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
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数组对应
char ch[5][5];//5X5矩阵
char ch1
;//密钥
char ch2
;//明文
char ch4;//无关字符
int len='a'-'A';
cout<<"输入密钥:";
cin>>ch1;
int flg=1;
while(flg==1)
{
for(int i=0;i<strlen(ch1);i++)//把所输入的密钥转化为大写字母
{
if(ch1[i]>'z'||ch1[i]<'a')
{
cout<<"请重新选择操作:"<<endl;
flg=0;break;
}
else
ch1[i]=ch1[i]-len;
}
if(flg==1)
{    for(int i=0;i<strlen(ch1);i++)//把密钥中的J都变为I
{
if(ch1[i]=='J')ch1[i]='I';
}
int i=0;int j=0;
//把密钥中的字母填入到矩阵中,并把该字母标记为已用
for(int k=0;k<strlen(ch1);k++)
{
for(int t=0;t<25;t++)
{
if(ch1[k]==letters[t]&&flag[t]==0)
{
ch[i][j]=letters[t];
flag[t]=1;
if(j<4)j++;
else {i++;j=0;}
}
}
}
for( int k=0;k<25;k++)//按字母表顺序把未用字母依次填入到矩阵中
{
if(flag[k]==0)
{
ch[i][j]=letters[k];
flag[k]=1;
if(j<4)j++;
else{i++;j=0;}
}
}
cout<<"密钥填充后的矩阵为: "<<endl;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
cout<<ch[i][j];
cout<<" ";
if(j==4)
cout<<endl;
}
cout<<endl;
cout<<"请输入明文(请输入英文字符):";
cin>>ch2;
cout<<"输入一个无关字符:";
cin>>ch4;
if(ch4>='a')
ch4=ch4-len;
for(int k=0;k<strlen(ch2);k++)//把所输入的明文转化为大写字母
{
if(ch2[k]>='a')
ch2[k]=ch2[k]-len;
}
for(int k=0;k<strlen(ch2);k++)//把明文中的J都变为I
{
if(ch2[k]=='J')
ch2[k]='I';
}
//为明文添加必要的无关字符以防止同一组的两个字符相同
for( int k=0;k<strlen(ch2);k+=2)
{
if(ch2[k]==ch2[k+1])
{
for(int t=strlen(ch2);t>k;t--)
ch2[t+1]=ch2[t];
ch2[k+1]=ch4;
}
}
//若明文有奇数个字符,则添加一个无关字符以凑够偶数个
if(strlen(ch2)%2!=0)
{
ch2[strlen(ch2)+1]=ch2[strlen(ch2)];//字符串结尾赋'\0'
ch2[strlen(ch2)]=ch4;//明文串尾插入无关字符
}
cout<<"经过处理后的明文为:";
for(int k=0;k<strlen(ch2);k+=2)
cout<<ch2[k]<<ch2[k+1]<<" ";
cout<<endl;
cout<<"其最终长度为:"<<strlen(ch2)<<endl;
//////////////////明文输入并整理完毕///////////////////////////////
for(int k=0;k<strlen(ch2);k+=2)
{
int m1,m2,n1,n2;
for(m1=0;m1<=4;m1++)
{for(n1=0;n1<=4;n1++)
{
if(ch2[k]==ch[m1][n1])break;
}
if(ch2[k]==ch[m1][n1])break;
}
for(m2=0;m2<=4;m2++)
{
for(n2=0;n2<=4;n2++)
{
if(ch2[k+1]==ch[m2][n2])break;
}
if(ch2[k+1]==ch[m2][n2])break;
}
m1=m1%5;
m2=m2%5;
if(n1>4){n1=n1%5;m1=m1+1;}
if(n2>4){n2=n2%5;m2=m2+1;}
if(m1==m2)
{
ch2[k]=ch[m1][(n1+1)%5];
ch2[k+1]=ch[m2][(n2+1)%5];
}
else
{
if(n1==n2)
{
ch2[k]=ch[(m1+1)%5][n1];
ch2[k+1]=ch[(m2+1)%5][n2];
}
else
{ch2[k]=ch[m1][n2];
ch2[k+1]=ch[m2][n1];
}
}
}
cout<<"加密后所得到的密文是:";
for(int k=0;k<strlen(ch2);k+=2)
cout<<ch2[k]<<ch2[k+1]<<" ";
cout<<endl;
}else break;
}

}

//解密算法
void decrypt()
{
const int N=100;
char letters[26]="ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
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数组对应
char ch[5][5];//5X5矩阵
char ch1
;//密钥
char ch2
;//密文
int len='a'-'A';
int flg=1;
cout<<"输入密钥:";
cin>>ch1;
while(flg==1)
{
for(int i=0;i<strlen(ch1);i++)//把所输入的密钥转化为大写字母
{if(ch1[i]>'z'||ch1[i]<'a')
{
cout<<"请重新选择操作:"<<endl;
flg=0;break;
}
else
ch1[i]=ch1[i]-len;
}
if(flg==1)
{    for(int i=0;i<strlen(ch1);i++)//把密钥中的J都变为I
{
if(ch1[i]=='J')ch1[i]='I';
}
int i=0;int j=0;
//把密钥中的字母填入到矩阵中,并把该字母标记为已用
for(int k=0;k<strlen(ch1);k++)
{
for( int t=0;t<25;t++)
{
if(ch1[k]==letters[t]&&flag[t]==0)
{
ch[i][j]=letters[t];
flag[t]=1;
if(j<4)j++;
else {i++;j=0;}
}
}
}
for( int k=0;k<25;k++)//按字母表顺序把未用字母依次填入到矩阵中
{
if(flag[k]==0)
{
ch[i][j]=letters[k];
flag[k]=1;
if(j<4)j++;
else{i++;j=0;}
}
}
cout<<"密钥填充后的矩阵为: "<<endl;
for(i=0;i<5;i++)

for(j=0;j<5;j++)
{
cout<<ch[i][j];
cout<<" ";
if(j==4)
cout<<endl;
}
cout<<endl;
/////////////////////矩阵生成完毕////////////////////////////
int f=0;
do{
cout<<"请输入密文(英文字符):";
cin>>ch2;
for(int k=0;k<strlen(ch2);k++)//把所输入的密文转化为大写字母
{
if(ch2[k]>='a')
ch2[k]=ch2[k]-len;
}
for( int k=0;k<strlen(ch2);k++)//把密文中的J都变为I
{
if(ch2[k]=='J')ch2[k]='I';
}
for( int k=0;k<strlen(ch2);k+=2)
{
if(ch2[k]==ch2[k+1])
{
cout<<"同一分组中不能出现相同字符!请重新输入。"<<endl;
f=1;
break;
}else f=2;
}
if(f==1)continue;
if(strlen(ch2)%2!=0)
{
cout<<"字符串不能为奇数个!请重新输入。"<<endl;
f=1;
}
else f=2;
}while(f==1);
//解密开始
for( int k=0;k<strlen(ch2);k+=2)
{
int m1,m2,n1,n2;
for(m1=0;m1<=4;m1++)
{
for(n1=0;n1<=4;n1++)
{
if(ch2[k]==ch[m1][n1])break;
}
if(ch2[k]==ch[m1][n1])break;
}
for(m2=0;m2<=4;m2++)
{
for(n2=0;n2<=4;n2++)
{
if(ch2[k+1]==ch[m2][n2])break;
}
if(ch2[k+1]==ch[m2][n2])break;
}
m1=m1%5;
m2=m2%5;
if(n1>4){n1=n1%5;m1=m1+1;}
if(n2>4){n2=n2%5;m2=m2+1;}
if(m1==m2)
{ch2[k]=ch[m1][(n1+4)%5];
ch2[k+1]=ch[m2][(n2+4)%5];
}
else
{
if(n1==n2)
{
ch2[k]=ch[(m1+4)%5][n1];
ch2[k+1]=ch[(m2+4)%5][n2];
}
else
{
ch2[k]=ch[m1][n2];
ch2[k+1]=ch[m2][n1];
}
}
}
cout<<"解密后所得到的明文是:";
for(int k=0;k<strlen(ch2);k+=2)
cout<<ch2[k]<<ch2[k+1]<<" ";
cout<<endl;
}
else break;
}

}

int main()
{

int n;
cout<<"请选择1加密2解密:"<<endl;
while(true)
{
cin>>n;
switch(n)
{
case 1:
encrypt();
break;
case 2:
decrypt();
break;
default:
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: