欢迎大家的评论和指导。算法请参考: http://en.wikipedia.org/wiki/Playfair_cipher
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define ENCRYPT 1
#define DECRYPT -1
// See in: The Cert C Secure Coding Standard
#define STRINGn) STRING_AGAINn)
#define STRING_AGAINn) #n
#define CHARS_TO_READ 100
FILE *fpSrc = NULL;
FILE *fpDest = NULL;
void flushbuf);
void getkeymatrixchar *)[5], char *); // 通过输入的密钥生成一个密钥矩阵
void printmatrixchar *)[5]);
int encryptchar *)[5]); // 加密函数
int decryptchar *)[5]); // 解密函数
void checkchar *, char *)[5], int); // 查找一对字母在密钥矩阵中对应的字母对
int mainvoid)
{
int choice;
char key[CHARS_TO_READ + 1];
char srcfile[CHARS_TO_READ + 1];
char destfile[CHARS_TO_READ + 1];
char keymatrix[5][5];
memsetkey, 0, CHARS_TO_READ + 1);
memsetsrcfile, 0, CHARS_TO_READ + 1);
memsetdestfile, 0, CHARS_TO_READ + 1);
memsetkeymatrix, 0, 25);
printf"===============/n"
"Please select:/n"
"1.Encrypt/n"
"2.Decrypt/n"
"0.Exit/n"
"Caution: This Program can only apply to ASCII file./n"
"===============/n");
do {
printf"Please input a num between 0 and 2:/n");
scanf"%d", &choice);
flushbuf);
}whilechoice < 0 || choice > 2);
switchchoice)
{
case 0:
return 0;
case 1:
printf"Please input the complete path of the file you want to encrypt:/n");
break;
case 2:
printf"Please input the complete path of the file you want to decrypt:/n");
break;
default: break;
}
scanf"%"STRINGCHARS_TO_READ)"s", srcfile);
flushbuf);
if fpSrc = fopensrcfile, "r") ) == NULL )
{
perror"fopen failed to open the file you want to read:");
exitEXIT_FAILURE);
}
printf"Please input the key:/n");
scanf"%"STRINGCHARS_TO_READ)"[^/n]s", key); // 不忽略空格,读入一整行
flushbuf);
getkeymatrixkeymatrix, key);
printmatrixkeymatrix);
printf"Please input the complete path of the file you want to create:/n");
scanf"%"STRINGCHARS_TO_READ)"s", destfile);
flushbuf);
if fpDest = fopendestfile, "w") ) == NULL )
{
perror"fopen failed to open the file you want to create:");
fclosefpSrc);
exitEXIT_FAILURE);
}
switchchoice)
{
case 1: encryptkeymatrix); break;
case 2: decryptkeymatrix); break;
default: break;
}
fclosefpSrc);
fclosefpDest);
system"pause>nul");
return 0;
}
void flushbuf)
{
char ch;
while ch = getchar)) != '/n' && ch != EOF && !feofstdin) );
}
void getkeymatrixchar *p)[5], char *srckey)
{
// 采用忽略Q的方法
int i = 0, j = 0;
char *q = srckey;
char temp[26];
memsettemp, 0, 26);
struprsrckey);
while*q != '/0')
{
if isalpha*q) != 0 && *q != 'Q')
{
ifstrchrtemp, *q) == NULL)
{
temp[i++] = *q;
}
}
q++;
}
forj = 'A'; j <= 'Z'; j++)
{
ifj == 'Q')
continue;
if strchrtemp, j) == NULL )
{
temp[i++] = j;
}
}
memcpyp, temp, 25);
}
void printmatrixchar *p)[5])
{
int i, j;
printf"The final key matrix:/n");
fori = 0; i < 5; i++)
{
forj = 0; j < 5; j++)
{
printf"%3c", **p + i) + j));
}
printf"/n");
}
}
int encryptchar *p)[5])
{
char chs[3];
char ch;
int turn = 0;
memsetchs, 0, 3);
ch = fgetcfpSrc);
while!feoffpSrc)) // EOF 是ASCII文件的结束符
{
ifisalphach) == 0)
{
ch = fgetcfpSrc);
continue;
}
else
{
chs[turn] = toupperch);
turn ^= 1; // 0^1==1 ,1^1 == 0,从而实现给chs[0]和chs[1]轮流赋值
}
ifturn == 0) // 如果turn==0 表明已经将一个字母对读入了chs[]
{
ifchs[1] == chs[0]) // 如果字母对中两个字母相同 插入X
{
chs[1] = 'X';
fseekfpSrc, -1L, SEEK_CUR);
}
checkchs, p, ENCRYPT);
fprintffpDest, "%s ", chs);
}
ch = fgetcfpSrc);
}
ifturn == 1) // 如果最后文件中还剩下一个字母 则给chs[1] 赋值 X
{
chs[1] = 'X';
checkchs, p, ENCRYPT);
fprintffpDest, "%s ", chs);
}
return 0;
}
int decryptchar *p)[5])
{
char chs[3];
memsetchs, 0, 3);
fscanffpSrc, "%2s", chs);
while!feoffpSrc))
{
checkchs, p, DECRYPT);
fprintffpDest, "%s ", chs);
fscanffpSrc, "%2s", chs);
}
return 0;
}
void checkchar *chs, char *p)[5], int d)
{
int i, j;
int row[2];
int col[2];
if strchrchs, 'Q') != NULL ) // 如果要加密的字母对中含有Q,则放弃对该字母对加密
{
return;
}
fori = 0; i < 5; i++)
{
forj = 0; j < 5; j++)
{
if**p + i) + j) == chs[0])
{
row[0] = i;
col[0] = j;
}
else if**p + i) + j) == chs[1])
{
row[1] = i;
col[1] = j;
}
}
}
ifrow[0] == row[1]) // 加密时同行右移,解密时相反:同行左移
{
chs[0] = **p + row[0]) + col[0] + 5 + d) % 5));
chs[1] = **p + row[1]) + col[1] + 5 + d) % 5));
}
else ifcol[0] == col[1]) // 加密时同列下移, 解密时相反:同列上移
{
chs[0] = **p + row[0] + 5 + d) % 5)) + col[0]);
chs[1] = **p + row[1] + 5 + d) % 5)) + col[1]);
}
else // 对角线
{
chs[0] = **p + row[0]) + col[1]);
chs[1] = **p + row[1]) + col[0]);
}
}