PlayFair密码的实现

#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];
		 }
	}
}

点赞