PlayFair密码的实现
2016-07-05 19:05
405 查看
#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]; } } }
相关文章推荐
- PRCT-1011: Failed to run “oifcfg”. Detailed error: null
- grains和pillar
- 【原创】使用.NET Core 1.0创建一个Self-Contained控制台应用
- leetcode 219. Contains Duplicate II
- Leetcode 217. Contains Duplicate
- Daily English
- 14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
- 14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
- 14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
- 【maven 报错】maven项目update之后报错One or more constraints have not been satisfied.
- 如何解决failed to push some refs to git
- Entity Framework Code-First(8):Configure Domain Classes
- HDU 2389 Rain on your Parade (二分匹配)
- Ruby on Rails框架程序连接MongoDB的教程
- POJ 3714 Raid
- login SMTP send mail error : Unable to read data from the transport connection: net_io_connectionclosed
- linux进程(fork,waitpid)
- Could not generate DH keypair
- 缓存相关(一)-InputStream、AIDL
- http://blog.csdn.net/u013256816/article/details/51161548