最近学习了密码学的PlayFair密码,于是我就用了C++语言将其写了出来,有些地方肯定用C语言里的数组只是更方便些,但是我为了巩固自己的C++知识,有些地方故意用了C++里面的东西,可能比较复杂!!
#include<iostream>
#include<vector>
#include<utility>
#include <algorithm>
#include<iterator>
#include<map>
#include<list>
#include<deque>
#include<string>
#define len ('a'-'A')
using namespace std;
class PlayFair
{
private:
char word;
vector<char> key_vec;
pair<int,int> ipar;
map<pair<int,int>,char> key_map;
deque<char> plaintext_En;
deque<char> plaintext_De;
deque<char> ciphertext_En;
deque<char> ciphertext_De;
public:
void Encryption();
void Decryption();
void Key();
};
void PlayFair::Key()
{
key_vec.clear();
key_map.clear();
cout<<"Please input the defult insertor: ";
cin>>word;
if(word>='a'&&word<='z') word-=len;
if(word == 'J') word = 'I';
char ch;
cout<<"Please input the key(Crtl+d to stop): ";
while(cin>>ch)
{
if(ch>'z'||ch<'A'||(ch>'Z'&&ch<'a')) continue;
if(ch>='a'&&ch<='z') ch-=len;
if(ch=='J') ch = 'I';
vector<char>::iterator iter = find(key_vec.begin(),key_vec.end(),ch);
if(key_vec.end()==iter)
key_vec.push_back(ch);
}
// cout<<key.size()<<endl;
for(char c='A';c<='Z';c++)
{
if(c=='j'||c=='J') continue;
vector<char>::iterator iter = find(key_vec.begin(),key_vec.end(),c);
if(key_vec.end()==iter)
key_vec.push_back(c);
}
int count=0;
cout<<"密钥的5*5的矩阵为:"<<endl;
vector<char>::iterator iter = key_vec.begin();
while(iter!=key_vec.end())
{
if(count%5==0&&count>0)
cout<<endl;
cout<<*iter++;
count++;
}
iter = key_vec.begin();
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
ipar = make_pair(i,j);
key_map.insert( make_pair(ipar,*iter++));
}
// 输出看看结果
cout<<endl;
}
void PlayFair::Encryption()
{
cout<<"您是否已经输入过密钥:?(y or n) ";
char ch;
cin>>ch;
if(ch!='y'&&ch!='Y') Key();
cout<<"Please input the Plaintext(ctrll+z to stop): "<<endl;
pair<char,char> cp;
plaintext_En.clear();
ciphertext_En.clear();
cin.clear();
string str;
char c[100];
//cin.ignore();
while(cin>>str)
{
str.copy(c,str.length(),0);
for(int i=0;i<str.length();i++)
{
if(c[i]>'z'||c[i]<'A'||(c[i]>'Z'&&c[i]<'a')) continue;
if(c[i]>='a'&&c[i]<='z') c[i]-=len;
if(c[i]=='J'||c[i]=='j') c[i] = 'I';
plaintext_En.push_back(c[i]);
}
}
cin.clear();
deque<char>::iterator ite = plaintext_En.begin();
while(ite!=plaintext_En.end()&&(ite+1)!=plaintext_En.end()) //查看相邻的字母是否是相同的,如果是,就往他们之间插入默认的字母
{
if(*ite==*(ite+1))
{
ite = plaintext_En.insert(ite+1,word);
ite++;
}
if(*ite!=*(ite+1))
ite+=2;
}
if(plaintext_En.size()%2!=0) //查看字母是否是偶数个,如果不是,就在最后添加一个默认的字母
plaintext_En.push_back(word);
ite = plaintext_En.begin();
map<pair<int,int>,char>::iterator itd1 ;
map<pair<int,int>,char>::iterator itd2 ;
while(ite!=plaintext_En.end())
{
itd1 = key_map.begin();
itd2 = key_map.begin();
while(itd1->second!=*ite)
itd1++;
while(itd2->second!=*(ite+1))
itd2++;
// cout<<*ite<<" "<<itd1->second<<endl;
// cout<<*(ite+1)<<" "<<itd2->second<<endl;
if(itd1->first.first==itd2->first.first)
{
if(itd1->first.second==4)
{
itd1 = key_map.find(make_pair(itd1->first.first,0));
itd2 = key_map.find(make_pair(itd1->first.first,itd2->first.second+1));
ciphertext_En.push_back((itd1->second));
ciphertext_En.push_back((itd2->second));
}
else
if(itd2->first.second==4)
{
itd1 = key_map.find(make_pair(itd1->first.first,itd1->first.second+1));
itd2 = key_map.find(make_pair(itd2->first.first,0));
ciphertext_En.push_back((itd1->second));
ciphertext_En.push_back((itd2->second));
}
else
if(itd1->first.second!=4&&itd2->first.second!=4)
{
itd1 = key_map.find(make_pair(itd1->first.first,itd1->first.second+1));
itd2 = key_map.find(make_pair(itd2->first.first,itd2->first.second+1));
ciphertext_En.push_back((itd1->second));
ciphertext_En.push_back((itd2->second));
}
}
else
if(itd1->first.second==itd2->first.second)
{
if(itd1->first.first==4)
{
itd1 = key_map.find(make_pair(0,itd1->first.second));
itd2 = key_map.find(make_pair(itd2->first.first+1,itd2->first.second));
ciphertext_En.push_back((itd1->second));
ciphertext_En.push_back((itd2->second));
}
else
if(itd2->first.second==4)
{
itd1 = key_map.find(make_pair(itd1->first.first+1,itd1->first.second));
itd2 = key_map.find(make_pair(0,itd2->first.second));
ciphertext_En.push_back((itd1->second));
ciphertext_En.push_back((itd2->second));
}
else
if(itd1->first.second!=4&&itd2->first.second!=4)
{
itd1 = key_map.find(make_pair(itd1->first.first+1,itd1->first.second));
itd2 = key_map.find(make_pair(itd2->first.first+1,itd2->first.second));
ciphertext_En.push_back((itd1->second));
ciphertext_En.push_back((itd2->second));
}
}
else
if(itd1->first.first!=itd2->first.first&&itd1->first.second!=itd2->first.second)
{
int p = itd1->first.second;
itd1 = key_map.find(make_pair(itd1->first.first,itd2->first.second));
itd2 = key_map.find(make_pair(itd2->first.first,p));
ciphertext_En.push_back((itd1->second));
ciphertext_En.push_back((itd2->second));
}
ite+=2;
}
cout<<"加密之后的文件为:"<<endl;
deque<char>::iterator ited = ciphertext_En.begin();
while(ited!=ciphertext_En.end()) cout<<*ited++;
}
void PlayFair::Decryption()
{
cout<<endl;
plaintext_De.clear();
ciphertext_De.clear();
cout<<"您是否已经输入过密钥:?(y or n) ";
char ch;
cin>>ch;
if(ch!='y'&&ch!='Y') Key();
cout<<"请输入密文:"<<endl;
string str;
char c[100];
cin.clear();
while(cin>>str)
{
str.copy(c,str.length(),0);
for(int i=0;i<str.length();i++)
{
if(c[i]>'z'||c[i]<'A'||(c[i]>'Z'&&c[i]<'a')) continue;
if(c[i]>='a'&&c[i]<='z') c[i]-=len;
if(c[i]=='J'||c[i]=='j') c[i] = 'I';
ciphertext_De.push_back(c[i]);
}
}
cin.clear();
//cout<<endl;
deque<char>::iterator ite = ciphertext_De.begin();
map<pair<int,int>,char>::iterator itd1 ;
map<pair<int,int>,char>::iterator itd2 ;
while(ite!=ciphertext_De.end()&&(ite+1)!=ciphertext_De.end())
{
itd1 = key_map.begin();
itd2 = key_map.begin();
while(itd1->second!=*ite)
itd1++;
while(itd2->second!=*(ite+1))
itd2++;
if(itd1->first.first==itd2->first.first)
{
if(itd1->first.second==0)
{
itd1 = key_map.find(make_pair(itd1->first.first,4));
itd2 = key_map.find(make_pair(itd1->first.first,itd2->first.second-1));
plaintext_De.push_back((itd1->second));
plaintext_De.push_back((itd2->second));
}
else
if(itd2->first.second==0)
{
itd1 = key_map.find(make_pair(itd1->first.first,itd1->first.second-1));
itd2 = key_map.find(make_pair(itd2->first.first,4));
plaintext_De.push_back((itd1->second));
plaintext_De.push_back((itd2->second));
}
else
if(itd1->first.second!=0&&itd2->first.second!=0)
{
itd1 = key_map.find(make_pair(itd1->first.first,itd1->first.second-1));
itd2 = key_map.find(make_pair(itd2->first.first,itd2->first.second-1));
plaintext_De.push_back((itd1->second));
plaintext_De.push_back((itd2->second));
}
}
else
if(itd1->first.second==itd2->first.second)
{
if(itd1->first.first==0)
{
itd1 = key_map.find(make_pair(4,itd1->first.second));
itd2 = key_map.find(make_pair(itd2->first.first-1,itd2->first.second));
plaintext_De.push_back((itd1->second));
plaintext_De.push_back((itd2->second));
}
else
if(itd2->first.second==0)
{
itd1 = key_map.find(make_pair(itd1->first.first-1,itd1->first.second));
itd2 = key_map.find(make_pair(4,itd2->first.second));
plaintext_De.push_back((itd1->second));
plaintext_De.push_back((itd2->second));
}
else
if(itd1->first.second!=0&&itd2->first.second!=0)
{
itd1 = key_map.find(make_pair(itd1->first.first-1,itd1->first.second));
itd2 = key_map.find(make_pair(itd2->first.first-1,itd2->first.second));
plaintext_De.push_back((itd1->second));
plaintext_De.push_back((itd2->second));
}
}
else
if(itd1->first.first!=itd2->first.first&&itd1->first.second!=itd2->first.second)
{
int p = itd1->first.second;
itd1 = key_map.find(make_pair(itd1->first.first,itd2->first.second));
itd2 = key_map.find(make_pair(itd2->first.first,p));
plaintext_De.push_back((itd1->second));
plaintext_De.push_back((itd2->second));
}
ite+=2;
}
cout<<"解密之后的文件为:"<<endl;
deque<char>::iterator ited = plaintext_De.begin();
while(ited!=plaintext_De.end())
cout<<*ited++;
cin.clear();
//cout<<endl;
}
int main()
{
cout<<"/*********************************PlayFair密码********************************/"<<endl;
PlayFair* pf = new PlayFair();
while(1)
{
int choose;
cout<<"请选择:1.加密;2.解密;3.退出程序"<<endl;
// if (2==choose) cin.ignore();
cin>>choose;
if(1==choose) pf->Encryption();
if(2==choose) pf->Decryption();
// if(choose!=1&&choose!=2&&choose!=3) continue;
if(3==choose) return 0;
cout<<endl;
}
return 0;
}