📄 blowfish.cpp
字号:
{
int i;
DWord xL, xR, xL0, xR0;
Word64 r;
xL0 = data64 >> 32;
xR0 = data64 & 0x00000000ffffffff;
for(i=0; i<16; i++)
{
xR = xL0 ^ gKeyBoxes[17-i];
xL = gBlowFishFunction(xR) ^ xR0;
xR0 = xR;
xL0 = xL;
}
xL = xR0 ^ gKeyBoxes[0];
xR = xL0 ^ gKeyBoxes[1];
r = xL;
r = (r << 32) | xR;
return r;
}
//------------------------------------------------------------------------------
// 函数:gBlowFishDeCode()
// 功能:解密用pSrc[8]表示的64位分组,pSrc和pDest的存储空间不得少于8
// 输入:加密的64位分组,从左至右存放在数组pSrc中
// 输出:解密后的64位分组,从左至右存放在数组pDest中
//------------------------------------------------------------------------------
void gBlowFishDeCode(Byte *pSrc, Byte *pDest)
{
int i;
DWord xL, xR, xL0, xR0;
Word64 r;
for(i=0, xL=0; i<4; i++) xL |= (pSrc[i] << (i*8));
for(i=0, xR=0; i<4; i++) xR |= (pSrc[i+4] << (i*8));
xR0 = xL ^ gKeyBoxes[17];
xL0 = xR ^ gKeyBoxes[16];
for(i=15; i>=0; i--)
{
xL = xL0;
xR = xR0;
xL0 = xR ^ gKeyBoxes[i];
xR0 = gBlowFishFunction(xR) ^ xL;
}
for(i=3; i>=0; i--) pDest[i] = xL0 >> (i*8);
for(i=3; i>=0; i--) pDest[i+4] = xR0 >> (i*8);
}
//------------------------------------------------------------------------------
// 函数:gBlowFishInit()
// 功能:初始化BlowFish算法的子密钥,并将他们放到全局变量gKeyBoxes中
// 输入:key用户输入密钥
//------------------------------------------------------------------------------
void gBlowFishInit(const char *key)
{
int i, j, k;
DWord tmp;
Word64 data64;
memset(gKeyBoxes, 0, sizeof(gKeyBoxes));
//(1)填充P盒子
for(i=0, j=0; i<18; i++)
{
tmp = 0;
for(k=0; k<3; k++)
{
tmp = (tmp << 8) | key[j++];
if(j >= strlen(key)) j = 0;
}
gKeyBoxes[i] = gPBox[i] ^ tmp;
}
//(2)填充S盒子
for(i=0; i<4; i++)
{
//因为填充P盒子的时候,占用了前面18个元素所以下标为i*256+j+18
for(j=0; j<256; j++) gKeyBoxes[i*256+j+18] = gSBox[i][j];
}
//(3)生成gKeyBoxes,包括18个P盒子32分组和1024个S盒子32分组
data64 = 0;
for(i=0; i<521; i++)
{
data64 = gBlowFishEnCode(data64);
gKeyBoxes[i*2] = data64 >> 32;
gKeyBoxes[i*2+1] = data64 & 0x00000000ffffffff;
}
}
//----以下为测试函数------------------------------------------------------------
void gotoxy(int x, int y)
{
COORD c;
c.X = x;
c.Y = y;
SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}
int wherex()
{
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
return info.dwCursorPosition.X;
}
int wherey()
{
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
return info.dwCursorPosition.Y;
}
void showErrorMsg(int code)
{
switch(code)
{
case -1: printf("...源文件读取失败\n"); break;
case -2: printf("...创建目标文件失败\n"); break;
case -3: printf("...密码文件格式错误\n"); break;
}
}
int gEnCodeFile(const char *srcFileName, const char *destFileName)
{
int i, nBytes, x, y, progress, p;
FILE *fpSrc, *fpDest;
long fileSize, iSize;
Byte buf[1024];
//(1)打开源文件,并得到文件大小
fpSrc = fopen(srcFileName, "rb");
if(fpSrc == NULL) return SRC_FILE_OPEN_FAILED;
fseek(fpSrc, 0, SEEK_END);
fileSize = ftell(fpSrc);
fseek(fpSrc, 0, SEEK_SET);
//(2)创建目标文件,并写入密文标志和源文件大小
fpDest = fopen(destFileName, "wb");
if(fpDest == NULL)
{
fclose(fpSrc);
return DEST_FILE_CREATE_FAILED;
}
fwrite(ENCODE_FILE_TAG, sizeof(char), ENCODE_FILE_TAG_LEN, fpDest);
fwrite(&fileSize, sizeof(long), 1, fpDest);
//(3)读取源文件,加密,并写入目标文件
printf("\n正在加密 ");
x = wherex(); y = wherey();
iSize = 0; progress = 0;
while(!feof(fpSrc))
{
memset(buf, 0, 1024);
nBytes = fread(buf, sizeof(Byte), 1024, fpSrc);
iSize += nBytes;
for(i=0; nBytes > 0; i+=8, nBytes-=8)
{
gBlowFishEnCode(buf+i, buf+i);
}
fwrite(buf, sizeof(Byte), i, fpDest);
p = (int)((float)iSize/fileSize*100);
if(p > 100) p = 100;
if(p > progress)
{
progress = p;
gotoxy(x, y);
printf("%d%%", progress);
}
}
fclose(fpSrc);
fclose(fpDest);
printf("\n加密成功\n");
return ENCODE_SUCCESSED;
}
int gDeCodeFile(const char *srcFileName, const char *destFileName)
{
int i, nBytes, x, y, progress, p;
char fileTag[ENCODE_FILE_TAG_LEN+1];
FILE *fpSrc, *fpDest;
long fileSize, iSize;
Byte buf[1024];
//(1)打开源文件,核对文件标志,并得到文件大小
fpSrc = fopen(srcFileName, "rb");
if(fpSrc == NULL) return SRC_FILE_OPEN_FAILED;
memset(fileTag, 0, sizeof(fileTag));
fread(fileTag, sizeof(char), strlen(ENCODE_FILE_TAG), fpSrc);
if(strcmp(fileTag, ENCODE_FILE_TAG) != 0)
{
fclose(fpSrc);
return ERROR_ENCODE_FILE;
}
fread(&fileSize, sizeof(long), 1, fpSrc);
//(2)创建目标文件
fpDest = fopen(destFileName, "wb");
if(fpDest == NULL)
{
fclose(fpSrc);
return DEST_FILE_CREATE_FAILED;
}
//(3)读取源文件,解密,并写入目标文件
printf("\n正在解密 ");
x = wherex(); y = wherey();
iSize = fileSize; progress = 0;
while(iSize > 0)
{
memset(buf, 0, 1024);
nBytes = fread(buf, sizeof(Byte), 1024, fpSrc);
for(i=0; nBytes > 0; i+=8, nBytes-=8)
{
gBlowFishDeCode(buf+i, buf+i);
}
if(i > iSize) i = iSize;
fwrite(buf, sizeof(Byte), i, fpDest);
iSize -= i;
p = (int)((float)(fileSize-iSize)/fileSize*100);
if(p > 100) p = 100;
if(p > progress)
{
progress = p;
gotoxy(x, y);
printf("%d%%", progress);
}
}
fclose(fpSrc);
fclose(fpDest);
printf("\n解密完成\n");
return DECODE_SUCCESSED;
}
void main()
{
int code;
char srcFileName[256], destFileName[256], key[14], ack[14];
char c;
printf("*--------------------------------------------------------------*\n");
printf("* BlowFish加密/解密算法教学演示--成都理工大学 邓飞 2004.8 *\n");
printf("*--------------------------------------------------------------*\n");
while(true)
{
printf("\n\n┏━━━━━━━━━━━━━━━━━━┓\n");
printf("┃ 加密(E),解密(D),退出(X) ┃\n");
printf("┗━━━━━━━━━━━━━━━━━━┛\n");
do
{
c = getch();
}while(c != 'e' && c != 'E' && c!= 'd' && c != 'D' && c!= 'x' && c != 'X');
if(c == 'X' || c == 'x') //退出
{
return;
}
else if(c == 'e' || c== 'E') //加密
{
printf("请输入加密文件名 ");
scanf("%s", srcFileName);
printf("请输入目标文件名 ");
scanf("%s", destFileName);
do
{
do
{
printf("请输入密码(<=14) ");
scanf("%s", key);
}while(strlen(key) > 14 || strlen(key) < 0);
printf("请确认密码 ");
scanf("%s", ack);
}while(strcmp(key, ack) != 0);
gBlowFishInit(key);
code = gEnCodeFile(srcFileName, destFileName);
if(code != ENCODE_SUCCESSED) showErrorMsg(code);
}
else //解密
{
printf("请输入解密文件名 ");
scanf("%s", srcFileName);
printf("请输入目标文件名 ");
scanf("%s", destFileName);
do
{
printf("请输入密码(<=14) ");
scanf("%s", key);
}while(strlen(key) > 14 || strlen(key) < 0);
gBlowFishInit(key);
code = gDeCodeFile(srcFileName, destFileName);
if(code != DECODE_SUCCESSED) showErrorMsg(code);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -