四種古典密碼的C++實現(3)-----Playfair密碼
//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[N];//金鑰
char ch2[N];//明文
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[N];//金鑰
char ch2[N];//密文
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;
}
相關文章
- 應用密碼學——古典密碼密碼學
- 古典密碼學 (一)密碼學
- 古典密碼的演化 (一)— 密碼學複習(二)密碼學
- 古典密碼的演化 (二)— 密碼學複習(三)密碼學
- 古典密碼的統計分析密碼
- 修改MySQL密碼的四種方法MySql密碼
- 密碼學課程設計 - 混合密碼的實現密碼學
- 分組密碼(一) — 密碼學複習(四)密碼學
- 3種生成高強度密碼的方法密碼
- python實現密碼破解Python密碼
- 現代密碼-公鑰密碼RSA密碼
- 用Abp實現找回密碼和密碼強制過期策略密碼
- 密碼安全:密碼設定要求,密碼爆破辦法,密碼歸類使用,密碼處置方案密碼
- 愷撒密碼Java/Python實現密碼JavaPython
- 分組密碼(四)AES演算法① — 密碼學複習(七)演算法密碼學
- 希爾密碼(hill密碼)密碼
- 密碼學與密碼安全:理論與實踐密碼學
- Go 如何實現 PHP 的密碼加密解密GoPHP密碼加密解密
- 《密碼學系列》|| 密碼學中的流密碼是怎麼回事?密碼學
- 實際序列密碼密碼
- flask框架如何實現修改密碼和免密登入功能Flask框架密碼
- 案例四:Shell指令碼生成隨機密碼指令碼隨機密碼
- 序列密碼與分組密碼密碼
- PAT1076 WiFi密碼(java實現)WiFi密碼Java
- C# 實現記住密碼功能C#密碼
- PHP處理密碼的幾種方式PHP密碼
- 實驗一-密碼引擎-3-加密API密碼加密API
- 實驗二-密碼引擎-3-sdf介面密碼
- 一個PHP通用隨機密碼的實現PHP隨機密碼
- PbootCMS忘記密碼後的重置密碼流程boot密碼
- 密碼密碼
- 應用密碼學 - 公鑰密碼密碼學
- 應用密碼學——分組密碼密碼學
- SSH實踐生成密碼密碼
- gitlab實現https及管理員密碼找回GitlabHTTP密碼
- 安卓實現賬號密碼儲存安卓密碼
- Windwos密碼匯出的幾種姿勢密碼
- 實驗一-密碼引擎-3-加密API研究密碼加密API
- 20211314實驗二-密碼引擎-3-sdf介面密碼