PlayFair密码的实现

来源:互联网 发布:淘宝评价添加小视频 编辑:程序博客网 时间:2024/05/21 13:55
#include <iostream>#include <string>using std::cout;using std::string;using std::cin;using std::endl;   void K_O(string* , string);   //这个函数void pfdcp(string et, string pf[5][5] , int alp[3][26] , string nct[]);  //解密函数//ct即cleartext,pf即密码矩阵,alp即放了pf坐标的字母表 void pfecp(string ct, string pf[5][5] , int alp[3][26] , string eText[]);  //加密函数
int main(){    string key; //密钥     string cleartext;  //明文      cout << "请输入密钥: " ;getline(cin, key);    cout << "请输入明文: " ;getline(cin, cleartext);    string ecptext = cleartext;    cout << "预设的密文: " << ecptext << endl; //    cout << key<<key.length() << endl;    string playfair[5][5] ;  //密码矩阵    string another;   //约定填充的字母    cout << "输入约定的填充字母: ";cin >> another;  string eText[cleartext.length()];    //string cText[ecptext.length()];     //去重int alp[3][26] = {{0*26},{0*26},{0*26}};int abLength=0;    for(int i=0 ; i<key.length() ; i++){         if(alp[0][((int)key[i]) - 97] == 0){ //应该用一个临时变量放这个强转      if(key[i] == 'i'||key[i] == 'j'){  //让i、j变得相同     alp[0][8]=alp[0][9]=1;    playfair[abLength/5][abLength%5] = key[i];    //添加alp在playfair里面的对应坐标    alp[1][8]=alp[1][9] = abLength/5;    alp[2][8]=alp[2][9] = abLength%5; abLength++;}else{alp[0][((int)key[i]) - 97] = 1;    playfair[abLength/5][abLength%5] = key[i];    alp[1][((int)key[i]) - 97] = abLength/5;alp[2][((int)key[i]) - 97] = abLength%5;    abLength++;}}}//检查 //for(int i=0; i<5 ; i++){//for(int j=0 ; j<5 ; j++)//cout << playfair[i][j] ;//cout << endl;//}//填充Playfair矩阵 for(int i = 0 ; i<26 ; i++){if (i == 8){if(alp[0][i] == 0){char x =i+97;playfair[abLength/5][abLength%5] = x;alp[1][i] = abLength/5;alp[2][i] = abLength%5; alp[1][i+1] = abLength/5;alp[2][i+1] = abLength%5;    abLength++;    alp[0][i+1] = 1;}}else if(alp[0][i] == 0 ){char x =i+97;playfair[abLength/5][abLength%5] = x;alp[1][i] = abLength/5;alp[2][i] = abLength%5;     abLength++;} } //填充检查 for(int i=0; i<5 ; i++){for(int j=0 ; j<5 ; j++)cout << playfair[i][j] << " | ";cout << endl; } //检查alp中的数组下标 // for(int i=0 ; i<3 ; i++){// for(int j=0 ; j<26 ; j++)// cout << alp[i][j] <<" | " ;// cout << endl;// }  //明文预处理 K_O(&cleartext, another);//明文输出检查 cout <<"明文预处理输出检查: " << cleartext <<endl;pfecp(cleartext , playfair , alp , eText);cout << "密文: ";for(int i=0; i<cleartext.length() ; i++)cout << eText[i] ;cout << endl;pfdcp(ecptext , playfair , alp , cText);cout << "明文: ";for(int i=0 ; i<ecptext.length() ; i++)cout << cText[i] ; return 0;}int check(string text){int i=0;for(; i<text.length()-2 ; i+=2){if(text[i] == text[i+1] ||(text[i] == 'i' && text[i+1] == 'j')||(text[i] == 'j' && text[i+1] == 'i'))return i;}if (i+1<text.length()){if(text[i] == text[i+1] ||(text[i] == 'i' && text[i+1] == 'j')||(text[i] == 'j' && text[i+1] == 'i'))return i;else return -1;}else return text.length()-1;} //明文的处理 //隐患:当后缀是z,或者中间插入之前是z,那就麻烦了 void K_O(string *str , string z){int indi = check(*str);if (indi == str->length()-1){*str+=z;K_O(str , z);}else if(indi == -1);else{str->insert(indi+1,z);K_O(str ,z);}}
<pre name="code" class="cpp">void pfdcp(string et, string pf[5][5] , int alp[3][26] , string nct[]){//遍历密文,每次两个 for(int i = 0 ; i<et.length() ; i+=2){//将密文字母转化为对应字母表的下标 int cti1 = (int)et[i];cti1-=97;int cti2 = (int)et[i+1];cti2-=97;//逆处理 int fline =alp[1][cti1],frow = alp[2][cti1];int sline = alp[1][cti2],srow = alp[2][cti2];if(fline == sline){//同行,还要判断是否黏着 if(frow - srow == -1){nct[i] = pf[fline][(frow+3)%5];//这里应该是frow-2+5,防止负数 nct[i+1] = pf[fline][(frow+4)%5];}else if (frow - srow == 1){nct[i] = pf[fline][(frow+2)%5];nct[i+1] = pf[fline][(frow+3)%5];}else{nct[i] = pf[fline][(frow+4)%5];nct[i+1] = pf[fline][(srow+4)%5];}}else if(frow == srow){ //同列,也要判断是否黏着 if(fline - sline == -1){nct[i] = pf[(fline+3)%5][frow];nct[i+1] = pf[(fline+4)%5][frow];}else if(fline - sline == 1){nct[i] = pf[(fline+2)%5][frow];nct[i+1] = pf[(fline+3)%5][frow];}else{nct[i] = pf[(fline+4)%5][frow];nct[i+1] = pf[(sline+4)%5][frow];}}else {//不同行列  nct[i] = pf[fline][srow];nct[i+1] = pf[sline][frow]; }}}
<pre name="code" class="cpp">void pfecp(string ct, string pf[5][5] , int alp[3][26] , string eText[]){//遍历明文,每次两个 for(int i = 0 ; i<ct.length() ; i+=2){//将明文字母转化为对应字母表的下标 int cti1 = (int)ct[i];cti1-=97;int cti2 = (int)ct[i+1];cti2-=97;//判断是否为j,如果是则改为i if(cti1 == 9)cti1-=1;else if(cti2 == 9)cti2-=1;//判断属于哪种情况 ,经过明文处理,只有1.同行,2.同列,3.都不同 int fline =alp[1][cti1],frow = alp[2][cti1];int sline = alp[1][cti2],srow = alp[2][cti2];if(fline == sline){//同行,还要判断是否黏着 if(frow - srow == -1){eText[i] = pf[fline][(frow+2)%5];eText[i+1] = pf[fline][(frow+3)%5];}else if (frow - srow == 1){eText[i] = pf[fline][(frow+1)%5];eText[i+1] = pf[fline][(frow+2)%5];}else{eText[i] = pf[fline][(frow+1)%5];eText[i+1] = pf[fline][(srow+1)%5];}}else if(frow == srow){ //同列,也要判断是否黏着 if(fline - sline == -1){eText[i] = pf[(fline+2)%5][frow];eText[i+1] = pf[(fline+3)%5][frow];}else if(fline - sline == 1){eText[i] = pf[(fline+1)%5][frow];eText[i+1] = pf[(fline+2)%5][frow];}else{eText[i] = pf[(fline+1)%5][frow];eText[i+1] = pf[(sline+1)%5][frow];}}else {//不同行列  eText[i] = pf[fline][srow];eText[i+1] = pf[sline][frow]; }}}


0 0