Data Encryption Standard (密码学作业一:DES)

#include  < stdio.h >
#include 
< string .h >

int  key[ 64 ] , tempkey[ 56 ] , subkey[ 16 ][ 48 ] ;            
int  choose ;
int  zhxz1[ 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 
        }
;
int  zhxz2[ 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     
        }
;
        
int  shiftleft[ 16 ] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1} ;

void  ChooseI() {
    
for (int i=0; i<56; i++)    
        tempkey[i] 
= key[zhxz1[i]-1];    
}


void  ChooseSubKey(  int  n ) {
    
for (int i=0; i<48; i++)
    subkey[n][i]
=tempkey[zhxz2[i]-1];
}


void  ShiftL(  int  n ) {
    
int temp ;
    temp 
= tempkey[0];
    
for ( int i=0; i<27; i++ )
    tempkey[i]
=tempkey[i+1];
    tempkey[
27]=temp;
    temp 
= tempkey[28] ;
    
for ( int i=28; i<55; i++ )
    tempkey[i]
=tempkey[i+1];
    tempkey[
55]=temp;
    
if (shiftleft[n]==2){
        temp 
= tempkey[0];
        
for ( int i=0; i<27; i++ )
        tempkey[i]
=tempkey[i+1];
        tempkey[
27]=temp;
        temp 
= tempkey[28] ;
        
for ( int i=28; i<55; i++ )
        tempkey[i]
=tempkey[i+1];
        tempkey[
55]=temp;    
    }
    
}


void  MakeSubKey() {
    ChooseI();
    
for ( int i=0; i<16; i++){
        ShiftL( i ) ;
        ChooseSubKey( i ) ;
    }
    
}


int  plaintext[ 64 ] , ciphertext[ 64 ] , ans[ 64 ];
int  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 
        }
;
            
typedef 
struct {
    
int num[32];    
}
PlainNum ;

PlainNum l[
17 ],r[ 17 ];
int  temp[ 48 ],s_temp[ 32 ];
int  expanper[ 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 
        }
;
int  s_box[ 8 ][ 4 ][ 16 =   {
    
// S1 
    14,     4,    13,     1,  21511,  8,  310,  612,  5,  9,  0,  7,
     
015,  7,  414,  213,  110,  61211,  9,  5,  3,  8,
     
4,  114,  813,  6,  2111512,  9,  7,  310,  5,  0,
    
1512,  8,  2,  4,  9,  1,  7,  511,  31410,  0,  613,
    
// S2 
    15,  1,  814,  611,  3,  4,  9,  7,  21312,  0,  510,
     
313,  4,  715,  2,  81412,  0,  110,  6,  911,  5,
     
014,  71110,  413,  1,  5,  812,  6,  9,  3,  215,
    
13,  810,  1,  315,  4,  211,  6,  712,  0,  514,  9,
    
// S3 
    10,  0,  914,  6,  315,  5,  11312,  711,  4,  2,  8,
    
13,  7,  0,  9,  3,  4,  610,  2,  8,  514121115,  1,
    
13,  6,  4,  9,  815,  3,  011,  1,  212,  51014,  7,
     
11013,  0,  6,  9,  8,  7,  41514,  311,  5,  212,
    
// S4 
     71314,  3,  0,  6,  910,  1,  2,  8,  51112,  415,
    
13,  811,  5,  615,  0,  3,  4,  7,  212,  11014,  9,
    
10,  6,  9,  01211,  71315,  1,  314,  5,  2,  8,  4,
     
315,  0,  610,  113,  8,  9,  4,  51112,  7,  214,
    
// S5 
     212,  4,  1,  71011,  6,  8,  5,  31513,  014,  9,
    
1411,  212,  4,  713,  1,  5,  01510,  3,  9,  8,  6,
     
4,  2,  1111013,  7,  815,  912,  5,  6,  3,  014,
    
11,  812,  7,  114,  213,  615,  0,  910,  4,  5,  3,
    
// S6 
    12,  11015,  9,  2,  6,  8,  013,  3,  414,  7,  511,
    
1015,  4,  2,  712,  9,  5,  6,  11314,  011,  3,  8,
     
91415,  5,  2,  812,  3,  7,  0,  410,  11311,  6,
     
4,  3,  212,  9,  515101114,  1,  7,  6,  0,  813,
    
// S7 
     411,  21415,  0,  813,  312,  9,  7,  510,  6,  1,
    
13,  011,  7,  4,  9,  11014,  3,  512,  215,  8,  6,
     
1,  4111312,  3,  7141015,  6,  8,  0,  5,  9,  2,
     
61113,  8,  1,  410,  7,  9,  5,  01514,  2,  312,
    
// S8 
    13,  2,  8,  4,  61511,  110,  9,  314,  5,  012,  7,
     
11513,  810,  3,  7,  412,  5,  611,  014,  9,  2,
     
711,  4,  1,  91214,  2,  0,  6101315,  3,  5,  8,
     
2,  114,  7,  410,  8131512,  9,  0,  3,  5,  611
}
;

int  permuted[ 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*/             
void  Init_Per() {
    
for ( int i=0;i<32;i++)
        l[
0].num[i]=plaintext[ip[i]-1];
    
for ( int i=0;i<32;i++)
        r[
0].num[i]=plaintext[ip[i+32]-1];
}


void  De_Per() {
    
for ( int i=0;i<32;i++)
        r[
0].num[i]=plaintext[ip[i]-1];
    
for ( int i=0;i<32;i++)    
        l[
0].num[i]=plaintext[ip[i+32]-1];
}



/*选择运算E(Expansion Permutation)*/  
void  ExpanPer(  int  n ) {
    
for ( int i=0;i<48;i++)
        temp[i]
=r[n-1].num[expanper[i]-1];
}


/*置换运算P*/
void  Permute() {
    
for ( int i=0;i<32;i++)
        temp[i]
=s_temp[permuted[i]-1];
}


/*S盒运算SBOX*/
void  SBOX() {
    
int row , col , svalue;
    
for ( int i=0;i<8;i++){
        row
=temp[i*6]*2+temp[i*6+5];
        col
=temp[i*6+1]*8+temp[i*6+2]*4+temp[i*6+3]*2+temp[i*6+4];
        svalue
=s_box[i][row][col];
        s_temp[i
*4]=svalue/8 ;
        svalue 
%= 8;
        s_temp[i
*4+1]=svalue/4;
        svalue 
%= 4;
        s_temp[i
*4+2]=svalue/2;
        svalue 
%= 2;
        s_temp[i
*4+3]=svalue ;
    }

}


/*加密函数*/  
void  EncryFunc(  int  n ) {
    
for ( int i=0;i<32;i++)
        l[n].num[i]
=r[n-1].num[i];
    
for ( int i=0;i<48;i++)
        temp[i]
=r[n-1].num[expanper[i]-1];
    
for ( int i=0;i<48;i++)
        temp[i] 
= temp[i]^subkey[n-1][i];
    SBOX();
    Permute();
    
for ( int i=0;i<32;i++)
    r[n].num[i] 
= temp[i]^l[n-1].num[i];        
}

/*解密函数*/
void  DecryFunc(  int  n ) {    
    
for ( int i=0;i<48;i++)
        temp[i]
=l[n-1].num[expanper[i]-1];    
    
for ( int i=0;i<48;i++)
        temp[i] 
= temp[i]^subkey[16-n][i];
    SBOX();
    
for ( int i=0;i<32;i++)
        temp[i]
=s_temp[permuted[i]-1];    
    
for ( int i=0;i<32;i++)
        r[n].num[i]
=l[n-1].num[i];
    
for ( int i=0;i<32;i++)
        l[n].num[i] 
= temp[i]^r[n-1].num[i];    
}


/*逆初始置换IP-1*/
void  IP_r() {
    
for ( int i=0;i<32;i++)
        ans[i]
=r[16].num[i];
    
for ( int i=0;i<32;i++)
        ans[
32+i]=l[16].num[i];
    
for ( int i=0;i<64;i++)
        ciphertext[ip[i]
-1]=ans[i];
}


void  DIP_r() {
    
for ( int i=0;i<32;i++)
        ans[i]
=l[16].num[i];
    
for ( int i=0;i<32;i++)
        ans[
32+i]=r[16].num[i];
    
for ( int i=0;i<64;i++)
        ciphertext[ip[i]
-1]=ans[i];
}

/*加密过程*/  
void  Encryption() {
    Init_Per( ) ;
    
for (int i=1;i<=16;i++)
    EncryFunc( i ) ;    
    IP_r();    
    printf(
"得出的密文为: ");    
    
for ( int i=0;i<64;i++)
    printf(
"%d",ciphertext[i]);
    printf(
" ");
}

/*解密过程*/  
void  Decryption() {
    De_Per();
    
for (int i=1;i<=16;i++)
    DecryFunc( i ) ;
    DIP_r();
    printf(
"得出的明文为: ");
    
for ( int i=0;i<64;i++)
    printf(
"%d",ciphertext[i]);
    printf(
" ");    
}


char  plain[ 100 ] , des_key[ 100 ];
int  len_plain , len_key ;

int  main() {
    
while (1){
        printf(
"请选择 1 加密 2 解密: ");        
        scanf(
"%d",&choose);
        
switch (choose){
            
case 1 : printf("请输入明文: ");break;
            
case 2 : printf("请输入密文: ");break;    
        }

        
        scanf(
"%s",plain);
        printf(
"请输入密钥: ");
        scanf(
"%s",des_key);

        
for ( int i=0;i<64;i++){
            plaintext[i]
=plain[i]-'0';
            key[i]
=des_key[i]-'0';
        }
                    
        MakeSubKey();
        
switch(choose){
                
case 1 : Encryption();break;
                
case 2 : Decryption();break;
        }

    }

    
return 0 ;    
}

/*
明文:(gZig^ZkZ)0110011101011010011010010110011101011110010110100110101101011010
密钥:([ZWgjVgn)0101101101011010010101110110011101101010010101100110011101101110
密文:1001011101001010111111111011111110000110000000100010110100011111
*/
 

 

还没有完全搞定,解密操作完全可以用更简便的方法,以及目前对输入的数据还有要求。

下次会做修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值