简介:des算法是一种对称加密,通过同一组秘钥进行加密和解密。利用64位秘钥对64位数据进行加密生成一组新的64位数据,其中的转换都是利用统一的表格数组对秘钥和数据转换(这些表格都是全网统一的,有些博客中分享的表格数据含有少数错误数据且极难发现,加解密数据截然不同)

例   网上的错误表格数据:

c语言des加解密 des算法的加解密过程c语言_c语言des加解密

 

以下为代码,这里的main函数传参加解密选项以及秘钥和数据,测试用只能传入64位秘钥和64位数据。选项1:加密,8字节秘钥可见字符,8字节数据可见字符 ; 选项2:加密,16位16进制秘钥,16位16进制数据(转换也是64位) ; 选项3:解密,16位16进制秘钥,16位16进制数据(转换也是64位)。。

流程:主要是表格对秘钥和数据的转换,以及分组后的秘钥对每轮数据的异或。
1、pc_1表对64位秘钥除去每字节的校验位后按表格位置打乱秘钥获得新的56位秘钥。
2、move表循环对56位秘钥按表格数据偏移16次,并将每次偏移后的数据记到16个内存中。(与位运算左移不同,此处左移会将左移的部分不到最后,而不是在尾部补0)
3、pc_2表在16组56位的秘钥中按表格数据顺序取内容会的16组48位秘钥,秘钥转换结束。
4、ip表打乱64位明文或密文。
5、将64位数据分成左右两部分L0和R0,进行16次循环(解密时key顺序倒过来输入到func即可):
       loop1:    L1=R0,R1=L0^func(R0 , key1);
       loop2:    L2=R1,R2=L1^func(R1 , key2);
       ......
       loop16:  L16=R15 ,R16=L15^func(R15 , key16);

步骤1: ext表对32位上轮右半段数据拓展成48位 ; 步骤2: 48位数据域48位秘钥key异或 ; 步骤3: 48位数据拆成八组6位二进制数据,6位数据首尾组成一段2位的二进制,中间四个组成一段4位的二进制得到(x,y)值,其中x为0到3,y为0到15.。。。8组xy值分别对应8个s盒数据使用xy为下标取值,取出的十进制数可转成4位二进制,8段合起来组成一个32位数据;步骤4: 左后p表将生成的32位数据打乱顺序。
6、再将左值和右值倒置R16L16,ipr表对这段64位数据打乱顺序得到最终结果。

 

头文件:tables.h

#ifndef _TABLES_H_
#define _TABLES_H_

//密钥第一次置换矩阵 
//64位秘钥跨过8 16 24 32 40 48 56 64位取得打乱的56位
int TBL_PC_1[56] = {                                
    57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
    10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
    63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
    14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4 
};

//半截秘钥偏移表
//将56位秘钥分为左右两段28位,分别左移16次并保存每次的值,再将左右两段合并成16组数据
const int TBL_MOVE[16] = {
    1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};

//密钥第二次置换矩阵 
//用上一步偏移后的16组数据,取56位秘钥的48位组成16段子秘钥
int TBL_PC_2[48] = {                           
    14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
    23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
    41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
    44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 
};

//IP置换矩阵 
//64位明文打乱顺序
int TBL_IP[64] = {                                      
    58, 50, 42, 34, 26, 18, 10, 2, 
    60, 52, 44, 36, 28, 20, 12, 4,
    62, 54, 46, 38, 30, 22, 14, 6, 
    64, 56, 48, 40, 32, 24, 16, 8,
    57, 49, 41, 33, 25, 17,  9, 1, 
    59, 51, 43, 35, 27, 19, 11, 3,
    61, 53, 45, 37, 29, 21, 13, 5, 
    63, 55, 47, 39, 31, 23, 15, 7 
};

//扩展矩阵
//分成两段32位左右值,分别拓展成48位,其中有重复位..48位再与48位子秘钥进行异或
int TBL_EXT[48] = {                                      
    32,  1,  2,  3,  4,  5,
     4,  5,  6,  7,  8,  9,
     8,  9, 10, 11, 12, 13, 
    12, 13, 14, 15, 16, 17,
    16, 17, 18, 19, 20, 21, 
    20, 21, 22, 23, 24, 25,
    24, 25, 26, 27, 28, 29, 
    28, 29, 30, 31, 32,  1 
};

//8个S盒
//48位数据按6位一段分成8组获得下标取s1-s8表中的值,获取32位数据。。
//6位数据首位2位一段,中间4位为一段   例:100011=(11,0001)=(3,1)  取第四行第二列的值
int TBL_S1[4][16] = {                        
    {14, 4,  13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7},
    { 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8},
    { 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0},
    {15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13},
};

int TBL_S2[4][16] = {  
    {15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10},
    { 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5},
    { 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15},
    {13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9},
};                                                                 

int TBL_S3[4][16] = {
    {10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8},
    {13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1},
    {13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7},
    { 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12},
};

int TBL_S4[4][16] = { 
    { 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15},
    {13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9},
    {10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4},
    { 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14},
};

int TBL_S5[4][16] = {  
    { 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9},
    {14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6},
    { 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14},
    {11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3},
};

int TBL_S6[4][16] = {  
    {12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11},
    {10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8},
    { 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6},
    { 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13},
};

int TBL_S7[4][16] = {
    { 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1},
    {13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6},
    { 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2},
    { 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12},
};

int TBL_S8[4][16] = {  
    {13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7},
    { 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2},
    { 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8},
    { 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11},
};

//P 盒
//8轮s盒查询结果获得的32位,再次进行顺序打乱
int TBL_P[32] = {                                             
    16, 7, 20, 21, 29, 12, 28, 17,
     1, 15, 23, 26, 5, 18, 31, 10,
     2,  8, 24, 14, 32, 27, 3,  9,  
    19, 13, 30, 6,  22, 11, 4,  25 
};

//逆IP置换矩阵
//16轮迭代后,再将左右两段交换,使用逆置换表打乱顺序得到最终加密结果 
int TBL_IPR[64] = {                                     
    40, 8, 48, 16, 56, 24, 64, 32,
    39, 7, 47, 15, 55, 23, 63, 31,
    38, 6, 46, 14, 54, 22, 62, 30,
    37, 5, 45, 13, 53, 21, 61, 29,
    36, 4, 44, 12, 52, 20, 60, 28,
    35, 3, 43, 11, 51, 19, 59, 27,
    34, 2, 42, 10, 50, 18, 58, 26,
    33, 1, 41,  9, 49, 17, 57, 25
};


#endif

源文件:

#include "tables.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#define _ENC_OPT_ 1
#define _DEC_OPT_ 2

unsigned char agSboxMapList[16][4] = {
    "0000",  /* 0*/
    "0001",  /* 1*/
    "0010",  /* 2*/
    "0011",  /* 3*/
    "0100",  /* 4*/
    "0101",  /* 5*/
    "0110",  /* 6*/
    "0111",  /* 7*/
    "1000",  /* 8*/
    "1001",  /* 9*/
    "1010",  /*10*/
    "1011",  /*11*/
    "1100",  /*12*/
    "1101",  /*13*/
    "1110",  /*14*/
    "1111",  /*15*/
};

int hex_str2bytes(unsigned char *in ,  unsigned char *out , int *outLen);
int proc_enc_dec(unsigned char *key , int key_len ,
            unsigned char *input , int in_put_len ,
            unsigned char *output , int *output_len , 
            int opt);
void bytes2bits_str(unsigned char *in , int inLen , unsigned char *out);
void bits_str2bytes(unsigned char *in , unsigned char *out , int *outLen);
void bits_str2deci(unsigned char *str , int *num);
void getBitsByPc1(unsigned char *in , unsigned char *out);
void getBitsListByMove(unsigned char *alKey56Bits , unsigned char alKeyLeft28BitsList[][28+1] , 
                        unsigned char alKeyRight28BitsList[][28+1]);
void getBitsListByPc2(unsigned char in[][56+1] , unsigned char out[][48+1]);
void getBitsByIp(unsigned char *in , unsigned char *out);
unsigned char *getBitsByFunc(unsigned char *data , unsigned char *key, unsigned char *result);
void xor_bits_str(unsigned char *str1 , unsigned char *str2 ,unsigned char *result);
void getBitsByIpr(unsigned char *in , unsigned char *out);


//16进制字符串转字节数组
int hex_str2bytes(unsigned char *in ,  unsigned char *out , int *outLen)
{
    int i = 0 , j = 0;
    int num = 0;
    int tmp = 0;
    for (i = 0 ; i < strlen((char *)in) ; i++)
    {
        if(in[i] < 58 && in[i] > 47) //0-9
            tmp = in[i]-48;
        else if(in[i] < 71 && in[i] > 64) //A-F
            tmp = 10+in[i]-65;
        else if(in[i] < 103 && in[i] > 96) //a-f
            tmp = 10+in[i]-97;
        else 
        {
            printf("Invalid arg!\n");
            return -1;
        }

        if(i%2 == 0)
            num = tmp*16;
        else
        {
            num += tmp;
            out[j++] = num;
        }
    }
    *outLen = j;
    return 0;
}

//字节数组转二进制字符数组
void bytes2bits_str(unsigned char *in , int inLen , unsigned char *out)
{
    //将二进制写为字符'0'和'1'而非0和1 , 方便打印观察
    int i = 0;
    for(i = 0 ; i<(inLen*8) ; i++)
    {
        if( in[i/8] & (0x01<<(7-i%8)) )
            out[i] = '1';
        else
            out[i] = '0';
    }
}

//二进制字符数组转字节数组
void bits_str2bytes(unsigned char *in , unsigned char *out , int *outLen)
{
    //将二进制字符数组'0'和'1'转换为字节数组    
    int i = 0 , j = 0;
    int num = 0;
    for(i = 0 ; i<strlen((char *)in) ; i++)
    {
        if(in[i] == '1')
        {
            num += pow(2,7-i%8);
        }
        if((i+1)%8 == 0)
        {
            out[j++] = num;
            num = 0;
        }
    }
    *outLen = j;
}

//二进制字符数组转十进制数
void bits_str2deci(unsigned char *str , int *num)
{
    int i = 0 , j = 0;
    *num = 0;
    //从最右最低位开始累加计算
    for(i = strlen((char *)str)-1 ; i >= 0 ; i--)
    {
        if(str[i] == '1')
        {
            *num += pow(2,j);
        }
        j++;
    }
}

//64位秘钥根据pc_1表获取56位秘钥
void getBitsByPc1(unsigned char *in , unsigned char *out)
{
    int i = 0;
    int index = 0;
    for(i = 0 ; i < 56 ; i++)
    {
        index = TBL_PC_1[i];
        out[i] = in[index-1];
    }
}
    
//对32段28位半段秘钥循环往左偏移,左边部分不丢弃填充到尾部
void getBitsListByMove(unsigned char *alKey56Bits , unsigned char alKeyLeft28BitsList[][28+1] , 
                        unsigned char alKeyRight28BitsList[][28+1])
{
    int i = 0;
    int ilOff = 0;

    memcpy(alKeyLeft28BitsList[0] , alKey56Bits , 28);
    memcpy(alKeyRight28BitsList[0] , alKey56Bits+28 , 28);

    for(i = 0 ; i < 16 ; i++)
    {
        ilOff = TBL_MOVE[i];
        memcpy(alKeyLeft28BitsList[i+1] , alKeyLeft28BitsList[i]+ilOff , 28-ilOff);
        memcpy(alKeyLeft28BitsList[i+1]+28-ilOff , alKeyLeft28BitsList[i] , ilOff);
        memcpy(alKeyRight28BitsList[i+1] , alKeyRight28BitsList[i]+ilOff , 28-ilOff);
        memcpy(alKeyRight28BitsList[i+1]+28-ilOff , alKeyRight28BitsList[i] , ilOff);
    }
}

//对16组56位左右两段秘钥数据根据pc_2选取48位并打乱顺序
void getBitsListByPc2(unsigned char in[][56+1] , unsigned char out[][48+1])
{
    int i = 0;
    int j = 0;
    int index = 0;

    for(i = 0 ; i < 16 ; i++)
    {
        for(j = 0 ; j < 48 ; j++)
        {
            index = TBL_PC_2[j];
            out[i][j] = in[i][index-1];
        }
        
    }
}

//64位加解密数据根据ip表打乱顺序
void getBitsByIp(unsigned char *in , unsigned char *out)
{
    int i = 0;
    int index = 0;
    for(i = 0; i<64 ; i++)
    {
        index = TBL_IP[i];
        out[i] = in[index-1];
    }
}

//16轮迭代处理函数  
//输入上一轮右半段32位数据和对应子秘钥
//拓展成48位,与子秘钥异或,每6位数据分成8组,收尾与中间段组成坐标x,y在s盒八组数据找到对应8个16进制数
//将8个16进制数转成二进制字符数组得到32位,最后根据评标打乱顺序得到函数结果
unsigned char *getBitsByFunc(unsigned char *data , unsigned char *key , unsigned char *result)
{
    int i = 0;
    int index = 0;
    char alEData[48+1] = {0};
    int x = 0;
    int y = 0;
    unsigned char alXBits[2+1] = {0};
    unsigned char alYBits[4+1] = {0};
    unsigned char alSboxRet[32+1] = {0};

    printf("proc data  [%s]\n" , data);
    //32位拓展成48位
    for(i = 0 ; i<48 ; i++)
    {
        index = TBL_EXT[i];
        alEData[i] = data[index-1];
    }
    printf("data by ext[%s]\n" , alEData);

    printf("XOR key    [%s]\n" , key);
    //与48位秘钥异或
    for(i = 0 ; i<48 ; i++)
    {
        if(alEData[i] == key[i])
            alEData[i] = '0';
        else
            alEData[i] = '1';
    }
    printf("XOR result [%s]\n" , alEData);
    
    //s盒取值
    //分8组6位取s盒坐标,对应s1-s8八组数据取值
    for(i = 0 ; i<8 ; i++)
    {
        memcpy(alXBits , alEData+i*6 , 1);
        memcpy(alXBits+1 , alEData+i*6+5 , 1);
        memcpy(alYBits , alEData+i*6+1 , 4);
        bits_str2deci(alXBits , &x);
        bits_str2deci(alYBits , &y);
        if(i+1 == 1)
        {
            //获得s表对应的16进制数,比转换为4位二进制字符依次赋值到结果,根据全局变量获取16进制映射值
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S1[x][y]] , 4);
        }
        else if(i+1 == 2)
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S2[x][y]] , 4);
        else if(i+1 == 3)
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S3[x][y]] , 4);
        else if(i+1 == 4)
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S4[x][y]] , 4);
        else if(i+1 == 5)
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S5[x][y]] , 4);
        else if(i+1 == 6)
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S6[x][y]] , 4);
        else if(i+1 == 7)
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S7[x][y]] , 4);
        else if(i+1 == 8)
            memcpy(alSboxRet+i*4 , agSboxMapList[TBL_S8[x][y]] , 4);
    }

    printf("after SBOX [%s]\n" , alSboxRet);

    //p表打乱
    for(i = 0; i < 32 ; i++)
    {
        index = TBL_P[i];
        *(result+i) = alSboxRet[index-1];
    }
    printf("after TBL_P[%s]\n" , result);

    return result;

}

//异或上一轮左值和迭代处理函数结果得到32位值,为本轮右值
void xor_bits_str(unsigned char *str1 , unsigned char *str2 , unsigned char *result)
{
    int i = 0;
    for(i = 0 ; i<32 ;i++)
    {
        if(*(str1+i) == *(str2+i))
        {
            memcpy(result+i , "0" , 1);
        }
        else
            memcpy(result+i , "1" , 1);
    }
}

//将16轮后的R16和L16组成的数据根据逆置换表打乱顺序得到加解密的最终结果
void getBitsByIpr(unsigned char *in , unsigned char *out)
{
    int i = 0;
    int index = 0;
    for(i = 0; i < 64 ;i++)
    {
        index = TBL_IPR[i];
        out[i] = in[index-1];
    }
}

//加解密主函数,根据opt判断加密还是解密
int proc_enc_dec(unsigned char *key , int key_len ,
            unsigned char *input , int in_put_len ,
            unsigned char *output , int *output_len ,
            int opt)
{
    int i = 0;
    unsigned char alKeyHexStr[16+1] = {0};
    unsigned char alKeyVisibleBits[1024] = {0};
    unsigned char alKey56Bits[56+1] = {0};
    unsigned char alKeyLeft28BitsList[17][28+1] = {{0}};
    unsigned char alKeyRight28BitsList[17][28+1] = {{0}};
    unsigned char alKey56BitsList[16][56+1] = {{0}};
    unsigned char alKey48BitsList[16][48+1] = {{0}};

    unsigned char alInputHexStr[16+1] = {0};
    unsigned char alInputVisibleBits[1024] = {0};
    unsigned char alInputByIp[64+1] = {0};
    unsigned char alInputLeftDataList[1+16][32+1] = {{0}};
    unsigned char alInputRightDataList[1+16][32+1] = {{0}};
    unsigned char alInputAfterFunc[32+1] = {0};
    unsigned char alInputAfterXor[32+1] = {0};
    unsigned char alInputLast[64+1] = {0};

    unsigned char alEncBinRet[64+1] = {0};
    unsigned char alEncStrRet[8+1] = {0};
    int ilEncStrRetLen = 0;
    unsigned char alEncHexRet[16+1] = {0};

    for(i = 0 ; i<8 ; i++)
    {
        sprintf((char *)(alKeyHexStr+i*2) , "%02x" , key[i]);
        sprintf((char *)(alInputHexStr+i*2) , "%02x" , input[i]);
    }
   
    //将参数中的8字节数据转换成64位二进制可见字符
    bytes2bits_str(key , strlen((char *)key) , alKeyVisibleBits);
    bytes2bits_str(input , strlen((char *)input) , alInputVisibleBits);

    puts("*************************key****************************");
    printf("64bits:[%s]\n" , alKeyVisibleBits);
    //获取56位秘钥
    getBitsByPc1(alKeyVisibleBits , alKey56Bits);
    puts("-----------------------------------");
    printf("56bits:[%s]\n" , alKey56Bits);
    //获取32段左偏移秘钥段
    getBitsListByMove(alKey56Bits , alKeyLeft28BitsList , alKeyRight28BitsList); 
    for(i = 0; i<16 ; i++)
    {
        memcpy(alKey56BitsList[i] , alKeyLeft28BitsList[i+1] , 28);
        memcpy(alKey56BitsList[i]+28 , alKeyRight28BitsList[i+1] , 28);
    }
    puts("-----------------------------------");
    for(i = 0 ; i<17 ; i++)
    {
        printf("i=[%d] , key[%s,%s]\n" , i , alKeyLeft28BitsList[i] , alKeyRight28BitsList[i]);
    }
    //16组56位秘钥生成48位最终子秘钥
    getBitsListByPc2(alKey56BitsList , alKey48BitsList);
    puts("-----------------------------------");
    for(i = 0 ; i<16 ; i++)
    {
        printf("i=[%d] , child_key[%s]\n" , i ,alKey48BitsList[i]);
    }
    //打乱加解密数据
    getBitsByIp(alInputVisibleBits , alInputByIp);
    puts("************************data****************************");
    printf("64bits data:[%s]\n" , alInputVisibleBits);
    printf("after TblIp:[%s]\n" , alInputByIp);

    //迭代16次左右交替处理数据
    memcpy(alInputLeftDataList[0] , alInputByIp , 32);
    memcpy(alInputRightDataList[0] , alInputByIp+32 , 32);
    for(i = 1 ; i<=16 ; i++)
    {
    puts("-----------------------------------");
    printf("round [%d]   (‘>>’指向此轮结果)\n" , i);
        //左值等于上一次的右值
        memcpy(alInputLeftDataList[i] , alInputRightDataList[i-1] , 32);
        printf(">>left var [%s]\n" , alInputLeftDataList[i-1]);
        //右值等于上一次的左值与函数处理后的上一次右值异或
        if(opt == _ENC_OPT_)
        {
            xor_bits_str(alInputLeftDataList[i-1] , 
                        getBitsByFunc(alInputRightDataList[i-1] , alKey48BitsList[i-1] , alInputAfterFunc) ,
                        alInputAfterXor);
        }
        else if(opt == _DEC_OPT_)
        {
            xor_bits_str(alInputLeftDataList[i-1] , 
                        getBitsByFunc(alInputRightDataList[i-1] , alKey48BitsList[16-i] , alInputAfterFunc) ,
                        alInputAfterXor);
        }
        else
        {
            printf("[ERROR] Invalid option!\n");
            return -1;
        }

        memcpy(alInputRightDataList[i] , alInputAfterXor , 32);
        printf("XOR left   [%s]\n" , alInputLeftDataList[i-1]);
        printf("XOR result [%s]\n" , alInputAfterXor);
        printf(">>right var[%s]\n" , alInputRightDataList[i]);
        printf("left,right [%s]~[%s]\n" , alInputLeftDataList[i] , alInputRightDataList[i]);
    }

    //最终再将右值和左值倒放
    memcpy(alInputLast , alInputRightDataList[16] , 32);
    memcpy(alInputLast+32 , alInputLeftDataList[16] , 32);
    puts("-----------------------------------");
    printf("data=R,L   [%s]\n" , alInputLast);
    //逆置换64位数据获得最终加解密结果
    getBitsByIpr(alInputLast , alEncBinRet);
    printf("after IPR  [%s]\n" , alEncBinRet);
    if(opt == _ENC_OPT_) puts("【加密ENCRYPT】 结果:");
    else if(opt == _DEC_OPT_) puts("【解密DECRYPT】 结果:");
    printf("InputHexStr[%s] ~ keyHexStr[%s]\n" , alInputHexStr , alKeyHexStr);
    printf("bin format [%s]\n" , alEncBinRet);
    //64为可见字符转换成8字节数据发回主函数
    bits_str2bytes(alEncBinRet , alEncStrRet , &ilEncStrRetLen);
    for(i = 0 ; i<8 ; i++)
    {
        sprintf((char *)(alEncHexRet+i*2) , "%02x" , alEncStrRet[i]);
    }
    memcpy(output , alEncStrRet , ilEncStrRetLen);
    *output_len = ilEncStrRetLen;
    printf("hex format [%s]\n" , alEncHexRet);
    puts("**************************************END*******************************");
    return 0;
}


int main(int argc,char **argv)
{
    if(argc != 4)
    {
        printf("Usage: des_tool [1/2/3] [key] [input]\n(1: [encrypt] char8 key , char8 data)\n(2: [encrypt] hex16 key , hex16 data)\n(3: [decrypt] hex16 key , hex16 data)\n");
        return -1;
    }
    if(strcmp(argv[1] , "1") != 0 && strcmp(argv[1] , "2") != 0 && strcmp(argv[1] , "3") != 0)
    {
        printf("Usage: des_tool [1/2/3] [key] [input]\n(1: [encrypt] char8 key , char8 data)\n(2: [encrypt] hex16 key , hex16 data)\n(3: [decrypt] hex16 key , hex16 data)\n");
        return -1;
    }
    if(strcmp(argv[1] , "1") == 0 && 
        (strlen(argv[2]) != 8 || strlen(argv[3]) != 8))
    {
        printf("Usage: des_tool [1/2/3] [key] [input]\n(1: [encrypt] char8 key , char8 data)\n(2: [encrypt] hex16 key , hex16 data)\n(3: [decrypt] hex16 key , hex16 data)\n");
        return -1;
    }
    else if(strcmp(argv[1] , "1") != 0 &&
        (strlen(argv[2]) != 16 || strlen(argv[3]) != 16))
    {
        printf("Usage: des_tool [1/2/3] [key] [input]\n(1: [encrypt] char8 key , char8 data)\n(2: [encrypt] hex16 key , hex16 data)\n(3: [decrypt] hex16 key , hex16 data)\n");
        return -1;
    }

    
    int ilRet = 0;
    int ilType = 0;
    unsigned char alKey[8+1] = {0};
    unsigned char alInput[8+1] = {0};
    unsigned char alOutput[8+1] = {0};
    int ilKeyLen = 0;
    int ilInputLen = 0;
    int ilOutputLen = 0;

    ilType = atoi(argv[1]);

    if(ilType == 1)
    {
        //可见明文,可见密码,加密
        strcpy((char *)alKey , argv[2]);
        strcpy((char *)alInput , argv[3]);
        ilRet = proc_enc_dec(alKey , strlen((char *)alKey) , alInput , strlen((char *)alInput) , 
                        alOutput , &ilOutputLen , _ENC_OPT_);
    }
    else if(ilType == 2)
    {
        //参数16进制明文和密码,加密
        if(hex_str2bytes((unsigned char *)argv[2] , alKey , &ilKeyLen))
            return -1;
        if(hex_str2bytes((unsigned char *)argv[3] , alInput, &ilInputLen))
            return -1;
        ilRet = proc_enc_dec(alKey , ilKeyLen , alInput , ilInputLen , 
                        alOutput , &ilOutputLen , _ENC_OPT_);
    }
    else if(ilType == 3)
    {
        //参数16进制密文和密码,解密
        if(hex_str2bytes((unsigned char *)argv[2] , alKey , &ilKeyLen))
            return -1;
        if(hex_str2bytes((unsigned char *)argv[3] , alInput, &ilInputLen))
            return -1;
        ilRet = proc_enc_dec(alKey , ilKeyLen , alInput , ilInputLen , 
                        alOutput , &ilOutputLen , _DEC_OPT_);
    }
    else
    {
        printf("Invalid args!");
        return -2;
    }

    if(ilRet != 0)
        return -1;

    return 0;
}

Makefile:

TARGET = des_tool
DEPEND = des_tool.o
CC = gcc -g -Wall
RM = rm -f
LIB = -lm

.c.o :
	$(CC) -c $^ -o $@

$(TARGET) : $(DEPEND)
	$(CC) $^ -o $@ $(LIB)

.PHONY : clean
clean :
	$(RM) $(TARGET) *.o

./des_tool  2 133457799bbcdff1 0123456789abcdef
加密结果:85e813540f0ab405

./des_tool  3 133457799bbcdff1 85e813540f0ab405
解密结果:0123456789abcdef

输入明文秘钥和数据加密:

./des_tool  1 12345678 aaaaaaaa
加密结果:72dca13c37223cf0

./des_tool  3 3132333435363738 72dca13c37223cf0
解密结果:6161616161616161