
#include <iostream.h>

#include < string.h>

#include <stdio.h>

#include <stdlib.h>

/*************************

time:2011 -3 -11 11:00

function:Playfair 算法

**************************/

//事先定义好的一个字母

#define MYWORD 'x'

//-----------------------

//Playfair 算法

void Playfair( char cinput[] , char matrix[5][5]);

//----------------------

//CreateKeyMatrix 创建密匙矩阵

void CreateKeyMatrix( char matrix[5][5] , char key[]);

void main()

{

//密匙矩阵

char matrix[5][5]={ 0} ;

//待输入密匙

char ccode[25]={0} ;

//待输入加密数据

char cinput[1024]={0} ;

//加密后数据

char coutput[1024] ={0} ;

int i,j ;

cout<< "Playfair加密算法程序"<<endl;

cout<< "请输入密匙:" ;

cin>>ccode;

//创建密匙矩阵

CreateKeyMatrix(matrix,ccode);

cout<< "请输入待加密数据:"<<endl;

//cin>>cinput ;

scanf( "%s",cinput);

//Playfair 加密

Playfair(cinput,matrix);

cout<< "Playfair加密得到的密文:"<<endl;

cout<<cinput <<endl;

system( "pause") ;

}

//---------------------

//Playfair算法第一步骤,

//将2个字母一样的中间插入事先已经约定好的字母MYWORD

void Playfair1( char cinput[])

{

char ctmp ;

char cinput1[1024] ;

int i,j ;

int len =strlen(cinput);

for(i =0;i <len -1; i=i+2)

{

if(cinput[i] ==cinput[i+1])

{

//如果相邻2个字母一样的话

//将cinput[i+1]之后的数据全部向后移动一位

len =strlen(cinput) ;

for(j =len ;j> i+1;j--)

{

cinput[j] =cinput[ j-1] ;

}

//将事先定义好的字母MYWORD插入到cinput[i+1]中

cinput[i+1] =MYWORD ;

}

//如果有字母插入cinput中,那么就要更新原数据长度

len=strlen(cinput);

}

}

//-----------------------------

//Playfair 算法第2步

//如果该明文不是2的倍数,那么在最后面加上事先定义好的MYWORD

void Playfair2( char cinput[])

{

int len=strlen(cinput) ;

if((len %2) ==0)

{

//如果是2的位数

return ;

}

else

{

//如果不是2的倍数

cinput[len]= MYWORD ;

return ;

}

}

//--------------------------------

//Playfair 算法第345步

//如果2个字母在同一行,那么循环左移

//如果2个字母在同一列,那么循环上移

//如果2个字母既不在同一列,也不再同一行,交叉互换

void Playfair345( char &a, char &b , char matrix[5][5])

{

int i,j ;

int rowa ,rowb ; //2个字母分别所在行

int cola ,colb ; //2个字母分别所在列

for( i=0;i<5 ;i++)

{

for( j=0;j< 5 ;j++)

{

//记录下a b 的行和列

if(matrix [i][j] == a)

{

rowa = i ;

cola = j ;

}

if(matrix[i][j] ==b)

{

rowb =i;

colb = j;

}

}

}

//-------------------

//判断rowa 是否等于 rowb

if(rowa == rowb )

{

//如果 a 和 b在同一行

if(cola != 4)

{

//如果a 不再这行的第5个,那么只需要将后面一个移动到前面一个就OKl

a =matrix[rowa][cola +1] ;

}

else

{

//如果 a 在这行的第5个,那么将这个数和第一个数交换

a = matrix[rowa][0];

}

if(colb != 4)

{

//如果b 不再这行的第5个,那么只需要将后面一个移动到前面一个就OKl

b =matrix[rowb][colb +1] ;

}

else

{

//如果 b 在这行的第5个,那么将这个数和第一个数交换

b = matrix[rowb][0];

}

//直接返回就OK了

return ;

}

//---------------------

//判断是否为同一列

if(cola ==colb)

{

//如果 a 和 b 是同一列

if(rowa !=4)

{

//如果a所在行不是第5行,

a =matrix[rowa+1][cola] ;

}

else

{

//如果a所在行是第5行

a =matrix[0][cola] ;

}

if(rowb !=4)

{

//如果b所在行不是第5行,

b =matrix[rowb+1][colb] ;

}

else

{

//如果a所在行是第5行

b =matrix[0][colb] ;

}

//直接返回就OK 了

return ;

}

//-----------------------

//判断 a 和 b 是否不为同一列,不为同一行

if((rowa !=rowb) &&(cola !=colb))

{

a = matrix[rowa][colb] ;

b = matrix[rowb][cola] ;

return ;

}

}

//-----------------------

//Playfair 算法

void Playfair( char cinput[] , char matrix[5][5])

{

int i ,len;

Playfair1(cinput);

Playfair2(cinput);

len =strlen(cinput);

for(i =0; i<len-1;i=i+2)

{

Playfair345(cinput[i],cinput[i+1] ,matrix);

}

}

//----------------------

//CreateKeyMatrix 创建密匙矩阵

void CreateKeyMatrix( char matrix[5][5] , char key[])

{

bool bin ;

bool bi,bj;

int i,j ,k ,m,n;

int len ;

char cword[27] = "abcdefghijklmnopqrstuvwxyz" ;

//将key 放入到matix中

for(i =0;i<5;i++)

{

for(j =0;j <5 ;j++)

{

if(key[i*5+j] != NULL)

{

//如果key[]不为空

matrix[i][ j] =key[i*5+j] ;

}

}

}

k =0 ;

//将剩余字母放入到matrix中

for(i =0;i<5;i++)

{

for(j =0;j <5 ;j++)

{

if(matrix[i][j] == NULL)

{

//如果matrix 中为空,那么加入剩余的字母

WordContinue:

bi= false;

bj = false;

//如果cword[k] ==i 或者 j,那么直接continue

if((cword[k] =='i') || (cword[k] =='j'))

{

for(m=0;m <5;m++)

{

for(n=0;n<5;n++)

{

if(matrix[m][n] == 'i')

{

bi = true;

}

if(matrix[m][n] == 'j')

{

bj = true ;

}

}

}

if( (bi == false ) && (bj == false))

{

//如果 i ,j 都不存在

goto AddContinue;

}

k++ ;

goto WordContinue;

}

AddContinue:

//设置字母不在matrix中

bin = false;

for(m = 0;m<5;m++)

{

for(n =0;n<5; n++)

{

if(matrix[m][n] ==cword[k])

{

//如果发现当前字符在密匙矩阵中,那么直接返回

bin = true ;

k++ ;

goto WordContinue;

}

}

if(bin == true)

{

//如果发现字母存在Matrix中,那么直接break

k++ ;

goto WordContinue;

}

}

if(bin == true )

{

//....什么都不做

k++ ;

goto WordContinue;

}

else

{

//如果字母不存在在Matrix中,那么添加到matrix中

matrix[i][j] = cword[k] ;

}

k++ ;

}

}

}

}