您的位置:首页 > 大数据 > 人工智能

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



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: