用c++写的PlayFair密码的加密与解密算法

时间:2022-04-20 18:23:27

最近学习了密码学的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;
}