⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blowfish.cpp

📁 标准C++书写的BlowFish加密算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
    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 + -