• DES解码


    DES加解密算法是一个挺老的算法了,现在给出它的C语言版。

    des.h

     1 #ifdef  __cplusplus
     2 extern "C" {
     3 #endif
     4 
     5 void setKey(const char key[8]);
     6 char* des(const char datas[]);
     7 char * dedes(const char datas[]);
     8 
     9 #ifdef  __cplusplus
    10 }
    11 #endif

    des_tables.h

      1 char table_IP[]                /* 初始置换表 IP    */
      2 = {    
      3     58, 50, 42, 34, 26, 18, 10,  2,    60, 52, 44, 36, 28, 20, 12,  4,
      4     62, 54, 46, 38, 30, 22, 14,  6,    64, 56, 48, 40, 32, 24, 16,  8,
      5     57, 49, 41, 33, 25, 17,  9,  1,    59, 51, 43, 35, 27, 19, 11,  3,    
      6     61, 53, 45, 37, 29, 21, 13,  5,    63, 55, 47, 39, 31, 23, 15,  7    
      7 };
      8 
      9 const static char table_FP[]                /* 末置换表 */
     10 = {
     11     40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
     12     38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
     13     36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
     14     34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41,  9, 49, 17, 57, 25
     15 };
     16 
     17 //= {    
     18 //    40,  8, 48, 16, 56, 24, 64, 32,     39,  7, 47, 15, 55, 23, 63, 31,
     19 //    38,  6, 46, 14, 54, 22, 62, 30,        37,  5, 45, 13, 53, 21, 61, 29,
     20 //    36,  4, 44, 12, 52, 20, 60, 28,        35,  3, 43, 11, 51, 19, 59, 27,
     21 //    34,  2, 42, 10, 50, 18, 58, 26,        33,  1, 41,  9, 49, 17, 57, 25    
     22 //};
     23 
     24 char table_PC_1[]                /* 密钥置换表PC_1  */
     25 = {    
     26     57, 49, 41, 33, 25, 17,  9,     1, 58, 50, 42, 34, 26, 18,
     27     10,  2, 59, 51, 43, 35, 27,    19, 11,  3, 60, 52, 44, 36,
     28     63, 55, 47, 39, 31, 23, 15,     7, 62, 54, 46, 38, 30, 22,
     29     14,  6, 61, 53, 45, 37, 29,    21, 13,  5, 28, 20, 12,  4    
     30 };
     31 
     32 
     33 char table_PC_2[]                /* 压缩置换表 PC_2  */
     34 = {    
     35     14, 17, 11, 24,  1,  5,     3, 28, 15,  6, 21, 10,
     36     23, 19, 12,  4, 26,  8,    16,  7, 27, 20, 13,  2,
     37     41, 52, 31, 37, 47, 55,    30, 40, 51, 45, 33, 48,
     38     44, 49, 39, 56, 34, 53,    46, 42, 50, 36, 29, 32    
     39 };
     40 
     41 
     42 
     43 char table_S[8][64]              /* 48->32 bit compression tables*/
     44 = {                    /* S[1]             */
     45     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
     46     0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
     47     4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
     48     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
     49     /* S[2]             */
     50     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
     51     3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
     52     0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
     53     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
     54     /* S[3]             */
     55     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
     56     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
     57     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
     58     1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
     59     /* S[4]             */
     60     7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
     61     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
     62     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
     63     3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
     64     /* S[5]             */
     65     2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
     66     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
     67     4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
     68     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
     69     /* S[6]             */
     70     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
     71     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
     72     9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
     73     4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
     74     /* S[7]             */
     75     4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
     76     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
     77     1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
     78     6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
     79     /* S[8]             */
     80     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
     81     1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
     82     7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
     83     2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11    
     84 };
     85 
     86 char table_P[]                /* P 盒置换  */
     87 = {    16,  7, 20, 21,    29, 12, 28, 17,     1, 15, 23, 26,     5, 18, 31, 10,
     88     2,  8, 24, 14,    32, 27,  3,  9,    19, 13, 30,  6,    22, 11,  4, 25    
     89 };
     90 
     91 char table_E[]
     92 = {
     93     32,  1,  2,  3,  4,  5,     4,  5,  6,  7,  8,  9,
     94     8,  9, 10, 11, 12, 13,    12, 13, 14, 15, 16, 17,
     95     16, 17, 18, 19, 20, 21,    20, 21, 22, 23, 24, 25,
     96     24, 25, 26, 27, 28, 29,    28, 29, 30, 31, 32,  1  
     97 };
     98 
     99 char table_move[] 
    100 ={
    101     1,1,2,2, 
    102     2,2,2,2, 
    103     1,2,2,2,
    104     2,2,2,1
    105 };

    des.c

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include"des_tables.h"
      4 #include"des.h"
      5 
      6 //保存这16轮的加密密钥<64位>
      7 char keys[17][8];
      8 //存着经过压缩置换后的 key
      9 char key_48[16][6];
     10 
     11 char data[16];
     12 //s盒置换结果缓冲区
     13 char data_32[4];
     14 char *data_left;
     15 char *data_right;
     16 
     17 
     18 //密钥置换
     19 void fun_InitReplacementKey(){
     20     register int i,j,l=0;
     21     register unsigned int k;
     22     register char *to_pos = keys[16];
     23     memset(to_pos,0,8);
     24     for(i=0,l=0;i<8;i++){
     25         for(j=7;j>0;j--){
     26             k = table_PC_1[l++]-1;                
     27             *to_pos = (*to_pos)| (( (*(keys[0]+(k>>3)) >>(7 - (k&0x07) ))&0x01  )<<j);                
     28         }
     29 
     30         to_pos++;
     31     }
     32 }
     33 
     34 //对密钥进行移位,并存在接下来下面的字节中
     35 void fun_MoveKey(int len , char*offset, char *dist){
     36     /////////////////////////
     37     ///错误了!!!! 是分两块进行循环移位 !!!!!!!
     38     ///< 已修改 ! 需要分左右部分 >
     39 
     40     register int i = len;
     41     unsigned char firstBit;
     42     static unsigned char *tmp;
     43     tmp =(unsigned char*)dist;
     44     memcpy(tmp,offset,8);
     45     firstBit =(unsigned char)tmp[0];
     46     firstBit = firstBit>>(8-len);
     47 
     48     //左边部分循环左移
     49     for(i=0;i< 3;i++){
     50         tmp[i] = (tmp[i]&0xfe) <<len ;        
     51         tmp[i] = tmp[i]|((tmp[i+1]>>(7-len))&0xff);
     52         tmp[i] = tmp[i]&0xfe;
     53     }
     54     
     55     tmp[i] = (tmp[i] &0xfe)<<len;
     56     tmp[i] = tmp[i]|(firstBit<<1);
     57     tmp[i] = tmp[i]&0xfe;
     58 
     59     firstBit =(unsigned char)tmp[++i];
     60     firstBit = firstBit>>(8-len);
     61 
     62     //右边部分循环左移
     63     for(i;i<7;i++){
     64         tmp[i] = (tmp[i]&0xfe) <<len ;        
     65         tmp[i] = tmp[i]|((tmp[i+1]>>(7-len))&0xff);
     66         tmp[i] = tmp[i]&0xfe;
     67     }
     68     tmp[i] = (tmp[i] &0xfe)<<len;
     69     tmp[i] = tmp[i]|(firstBit<<1);
     70     tmp[i] = tmp[i]&0xfe;
     71 
     72 }
     73 
     74 //对密钥进行压缩置换并保存到指定位置
     75 void fun_ReplacementCompressKey(char* offset,char *dist){
     76     //压缩置换是在 0-56位进行.需要先对64位密钥进行压缩为56位在进行48位选择
     77     register int i,j,k,l;
     78     register char dt;
     79     register unsigned char* tmp  = (unsigned char*)offset;
     80     char mid_tmp[7];
     81 
     82     for(i=0;i<7;i++){
     83         mid_tmp[i] = (tmp[i]<<(i)) | ((tmp[i+1])>>(7-i));
     84     }        
     85 
     86     memset(dist,0,7);
     87     //进行置换
     88     for(i=0,l=0;i<6;i++){
     89         for(dt =0,j=7;j>=0;j--){
     90             k = table_PC_2[l++]-1;        
     91             dt = dt|(( (*(mid_tmp+(k>>3)) >>(7 - k&0x07 ))&0x01  )<<j);
     92             if(j==0)
     93                 break;
     94         }
     95         dist[i] = dt;
     96     }
     97 }
     98 
     99 /**********************************************/
    100 
    101 
    102 /**********************************************/
    103 //加密过程
    104 
    105 //初始置换 ip 
    106 //从offset位置开始将数据置换到 data[8-15]字节 ,然后重新复制到data[0-7]中
    107 void fun_initReplacement(const char *offset){
    108     register int i,j,l;
    109     register unsigned char k,*tmp,*to;
    110     //将数据块区域重置为 0 
    111     tmp = (unsigned char*)offset;
    112     to = (unsigned char* )(data+8);
    113     memset(to,0,8);
    114     for(i=0,l=0;i<8;i++){
    115         for(j=7;j>=0;j--){
    116             k = table_IP[l++]-1;
    117             to[i] = to[i] | ((( *(tmp+(k>>3))>>(7- (k &0x07)))&0x01)<<j);
    118             if(j==0)
    119                 break;
    120         }
    121     }
    122     memcpy(data,data+8,8);
    123     //初始化指针
    124     data_left = data;
    125     data_right = data+4;
    126 }
    127 
    128 //末置换 fp
    129 void fun_finalReplacement(){
    130     //数据块存在 data[0]-data[7]中 !
    131     //置换临时空间 data[8]-data[15]    
    132     register int i,j,l;
    133     register unsigned char k,*tmp,*to;
    134     //将数据块区域重置为 0 
    135     tmp = (unsigned char*)data;
    136     to = (unsigned char*)(data+8);
    137     for(i=0,l=0;i<8;i++){
    138         for(j=7;j>=0;j--){
    139             k = table_FP[l++]-1;
    140             to[i] = to[i] | ((( *(tmp+(k>>3))>>(7- (k &0x07)))&0x01)<<j);
    141             if(j==0)
    142                 break;
    143         }
    144     }
    145     memcpy(data,to,8);
    146 
    147 }
    148 
    149 //扩展置换
    150 void fun_expandReplacement_32To48(){
    151     //////////将右边的数据扩展至 48 位 !
    152     register int i,j;
    153     register unsigned char k,l,*tmp,*to_pos;
    154     tmp = (unsigned char *)data_right;
    155     to_pos = (unsigned char*)(data+8);
    156     memset(to_pos,0,8);
    157     //printf("
    ---------- 扩展置换 ---------
    ");
    158     for(i=0,l=0;i<6;i++){
    159         for(j=7 ,k=0;j>=0;j--){
    160             k = table_E[l++]-1;
    161             *to_pos = (*to_pos)| (((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01)<<j);
    162             //printf("%d  %d  %x 
    ",l,k,((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01));
    163             if(j==0)
    164                 break;
    165         }
    166         to_pos++;
    167     }
    168 }
    169 
    170 //加 密钥 异或
    171 void fun_xor_48(char *ktmp){
    172     register int i;
    173     char *dtmp = data+8;
    174     for(i=0;i<6;i++){
    175         dtmp[i] = dtmp[i]^ktmp[i];
    176 
    177     }
    178 }
    179 
    180 // s盒置换
    181 void fun_S_Replacement(){
    182     // s盒工作原理 : 48位 分成8组.每组6位   0位和5位组成行定位, 1-4位组成列定位.
    183     // 定位出来的数据即为替换后的 4 位数据
    184     register unsigned char row,col,ctmp,index,i;
    185     register char *dtmp;
    186     static char tmp[4];
    187     dtmp = data+8;
    188     memset(tmp,0,4);
    189     //((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01)
    190     for(index =0,ctmp=0,i=0;i< 8 ;i++){
    191         // row 为:index 接下来第零位和第五位
    192         row = (((*(dtmp+((index)>>3))>>((7-((index)&0x07))))&0x01)<<1); //第0位
    193         row|=(((*(dtmp+((index+5)>>3))>>((7-((index+5)&0x07))))&0x01))&0x03;//第5位
    194 
    195         col =(((*(dtmp+((index+1)>>3))>>((7-((index+1)&0x07))))&0x01)<<3); //第1位
    196             col|= (((*(dtmp+((index+2)>>3))>>((7-((index+2)&0x07))))&0x01)<<2);    //第2位
    197             col|= (((*(dtmp+((index+3)>>3))>>((7-((index+3)&0x07))))&0x01)<<1);    //第3位
    198             col|= (((*(dtmp+((index+4)>>3))>>((7-((index+4)&0x07))))&0x01))&0x0f;//第4位
    199         ctmp = table_S[i][(row<<4)+col];
    200 
    201         //写入4位
    202         tmp[i>>1] = tmp[i>>1] | ((ctmp&0xf)<<(((~i)&0x01)<<2));
    203         index+=6;
    204     }
    205     memcpy(data+8,tmp,4);
    206 }
    207     
    208 
    209 //P盒置换
    210 void fun_P_Replacement(){
    211     register unsigned char i,k,l;
    212     static char tmp[4],j;
    213     register char *offset =data + 8;
    214     memset(tmp,0,4);
    215     for(i=0,l=0;i<4;i++){
    216         for(k=0,j=7;j>=0;j--){
    217             k = table_P[l++]-1;            
    218             tmp[i] = tmp[i] |((( * (offset+(k>>3)))>>(7 - (k&0x07))&0x01)<<j);
    219             if(j==0)
    220                 break;
    221         }
    222     }    
    223     memcpy(data+8,tmp,4);
    224 }
    225 
    226 //左右域异或
    227 void fun_xor_32(){
    228     register char i;
    229     for(i=0;i<4;i++){
    230         data_left[i] = data_left[i]^data[8+i];
    231     }
    232 }
    233 
    234 
    235 //设置 密码 <生成过程所有密码>
    236 void setKey(const char key[8]){    
    237     register int i;
    238     register char*offset,*to,*ct;
    239     memcpy(keys[0],key,8);
    240     fun_InitReplacementKey();
    241     offset =  keys[16];
    242     to = keys[0];
    243     ct = key_48[0];
    244     //16轮迭代算出需要的 <key>
    245     for(i=0;i<16;i++){
    246         fun_MoveKey(table_move[i],offset,to);
    247         fun_ReplacementCompressKey(to,ct);
    248         offset = to;
    249         ct+=6;
    250         to+=8;
    251     }
    252 }
    253 
    254 
    255 //加密
    256 char* des(const char datas[]){
    257     int i=0;
    258     static char *swapeTmp;
    259     fun_initReplacement(datas);
    260     for(i=0;i<15;i++){
    261         fun_expandReplacement_32To48();
    262         fun_xor_48(key_48[i]);
    263         fun_S_Replacement();
    264         fun_P_Replacement();
    265         fun_xor_32();
    266         swapeTmp = data_left;        
    267         data_left =data_right;
    268         data_right =swapeTmp;
    269     }//经检验前 15 轮可以正确运算...
    270     {//第16轮
    271         fun_expandReplacement_32To48();
    272         fun_xor_48(key_48[i]);
    273         fun_S_Replacement();
    274         fun_P_Replacement();
    275         fun_xor_32();
    276         //printf("
    ---- 16 轮-----
    Data: %x Left: %x Right: %x ",data,data_left,data_right);
    277         //现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
    278         memcpy(data+8,data,4);
    279         memcpy(data,data+4,4);
    280         memcpy(data+4,data+8,4);
    281         memset(data+8,0,8);
    282     }
    283     //末置换!
    284     fun_finalReplacement();
    285     return data;
    286 }
    287 
    288 //解密算法
    289 char * dedes(const char datas[]){
    290     int i=0;
    291     static char *swapeTmp;
    292     fun_initReplacement(datas);
    293     for(i=15;i>0;i--){
    294         fun_expandReplacement_32To48();
    295         fun_xor_48(key_48[i]);
    296         fun_S_Replacement();
    297         fun_P_Replacement();
    298         fun_xor_32();
    299         swapeTmp = data_left;        
    300         data_left =data_right;
    301         data_right =swapeTmp;
    302     }//经检验前 15 轮可以正确运算...
    303     {//第16轮
    304         fun_expandReplacement_32To48();
    305         fun_xor_48(key_48[i]);
    306         fun_S_Replacement();
    307         fun_P_Replacement();
    308         fun_xor_32();
    309         //现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
    310         memcpy(data+8,data,4);
    311         memcpy(data,data+4,4);
    312         memcpy(data+4,data+8,4);
    313         memset(data+8,0,8);
    314     }
    315     //末置换!
    316     fun_finalReplacement();
    317     data[8]='';
    318     return data;
    319 }
  • 相关阅读:
    collections模块整理
    jQuery 事件
    前端开发问题点
    无线wifi
    MySQL 数据库--SQL语句优化
    MySQL 数据库--索引原理与慢查询优化
    MySQL 数据库--内置功能
    MySQL 数据库--权限管理
    MySQL -Naivacat工具与pymysql模块
    MySQL 数据库 -- 数据操作
  • 原文地址:https://www.cnblogs.com/guoxiaoqian/p/3915400.html
Copyright © 2020-2023  润新知