密码学第二次 实验S-DES

 奋战了好长时间,终于写出了一个S-DES了,以前也没有好好写过一个像样的程序。--!

源代码如下:

#include <stdio.h>
#include <stdlib.h>

#define EN 0 //加密
#define DE 1 //解密

int encr_sdes(char *,char *,char *);//加密函数
int decr_sdes(char *,char *,char *);//解密函数
//***********加密流程函数
static unsigned int getkey(char *);//用户任意输入字符串,取低十位
static unsigned char ip(unsigned char);//初始置换
static unsigned char fk(unsigned char,unsigned char);
static unsigned char nip(unsigned char);//逆初始置换
//*********fk内部调用函数
static unsigned char ep(unsigned char);
static unsigned char sbox(unsigned char);
static unsigned char p4(unsigned char);
//*********生成密钥函数***********
static unsigned int _shift(unsigned int,unsigned int);
static unsigned char p8(unsigned int key);
static unsigned int p10(unsigned int key);
//************************函数定义******************************
int encr_sdes(char *key,char *infilename,char *outfilename)
{
    unsigned int start_key = 0,getf_p10 = 0,shift1 = 0,shift2 = 0;
    unsigned char k1 = '/0',k2 = '/0';
    FILE * fp_in,*fp_out;
    unsigned char ch = '/0',ch1 = '/0',ch2 = '/0',ch3 = '/0';
    unsigned count = 0;
   
    start_key = getkey(key);//获取初始密钥,取有效十位
    getf_p10 = p10(start_key);//对初始十位密钥做p10置换
    shift1 = _shift(getf_p10,1);
    k1 = p8(shift1);//k1产生过程
   
    shift2 = _shift(shift1,2);
    k2 = p8(shift2);//k2产生过程
   
    //********打开待加密文件和加密后输出定向文件
    if((fp_in = fopen(infilename,"rb")) == NULL)
 {
  printf("Error to open the file %s",infilename);
  exit(1);
 } 
 if((fp_out = fopen(outfilename,"wb+")) == NULL)
 {
  printf("Error to open the file %s",outfilename);
  exit(1);
 }
 //********加密流程
 
    do
    {
   
        ch = fgetc(fp_in);
        ch1 = ip(ch);
        ch2 = fk(fk(ch1,k1),k2);       
        ch3 = nip((ch2 >> 4) | (ch2 << 4));
        fputc(ch3,fp_out);
        count = count + 1;   
    }while(!feof(fp_in));
 
 fclose(fp_in);
 fclose(fp_out);
 return 0;
}

int decr_sdes(char *key,char *infilename,char *outfilename)
{
    unsigned int start_key = 0,getf_p10 = 0,shift1 = 0,shift2 = 0;
    unsigned char k1 = '/0',k2 = '/0';
    FILE * fp_in,*fp_out;
    unsigned char ch = '/0',ch1 = '/0',ch2 = '/0',ch3 = '/0';
   
    start_key = getkey(key);//获取初始密钥,取有效十位
    getf_p10 = p10(start_key);//对初始十位密钥做p10置换
    shift1 = _shift(getf_p10,1);
    k1 = p8(shift1);//k1产生过程
   
    shift2 = _shift(shift1,2);
    k2 = p8(shift2);//k2产生过程
   
    //********打开待加密文件和加密后输出定向文件
    if((fp_in = fopen(infilename,"rb")) == NULL)
 {
  printf("Error to open the file %s",infilename);
  exit(1);
 } 
 if((fp_out = fopen(outfilename,"wb+")) == NULL)
 {
  printf("Error to open the file %s",outfilename);
  exit(1);
 }
 //********加密流程
 
    do
    {
        ch = fgetc(fp_in);
        ch1 = ip(ch);
        ch2 = fk(fk(ch1,k2),k1);       
        ch3 = nip((ch2 >> 4) | (ch2 << 4));
        fputc(ch3,fp_out);    
    }while(!feof(fp_in));
 
 fclose(fp_in);
 fclose(fp_out);
 return 0;
}
//**********fk函数实现****************
static unsigned int getkey(char *_key)
{
    unsigned int newkey = 0;
    unsigned int i = 0,j = 0;
    char temp = '/0';
    newkey = _key[1] & 3;
    newkey <<= 8;
    j = _key[0] & 0xff;
    newkey |= j;
  
    return newkey;
}
static unsigned char fk(unsigned char _ch,unsigned char k)
{
    unsigned char left4 = '/0',right4 = '/0';
    unsigned char ch1 = '/0',ch2 = '/0',ch3 = '/0',ch4 = '/0',ch5 = '/0';
    left4 = ((_ch & 0xf0) >> 4);
    right4 = _ch & 0x0f;
    ch1 = ep(right4);//ep扩展置换
    ch2 = ch1 ^ k;//ep返回值和k1相与
    ch3 = sbox(ch2);//sbox返回值将作为p4函数参数
    ch4 = p4(ch3);
    ch5 = ((left4 ^ ch4) | (right4 << 4));
   
    return ch5; 
}
static unsigned char ip(unsigned char _ch)
{
    int i;
 int ip[8] = {2,6,3,1,4,8,5,7};
 unsigned char temp_ch = '/0';
    for(i = 0;i < 8;i++)//置换移位运算
  temp_ch |= (((_ch >> (8-ip[i])) & 1) << (7-i));
 
 return temp_ch;
}
static unsigned char ep(unsigned char r_ch)
{
    //ep[8] = {4,1,2,3,2,3,4,1};
 unsigned char temp_ch1 = '/0',temp_ch2 = '/0',
            temp_ch3 = '/0',temp_ch4 = '/0';
 //假设IP置换后的右四位不变,左四位为0000
 temp_ch1 = (r_ch << 7) | ((r_ch << 1) & 2);
 temp_ch2 = ((r_ch << 3) & 64) | ((r_ch >> 3) & 1);
 temp_ch3 = ((r_ch << 3) & 32) | ((r_ch << 1) & 8);
 temp_ch4 = ((r_ch << 3) & 16) | ((r_ch << 1) & 4);
    //返回值为扩展置换后的值
    return (temp_ch1 | temp_ch2 | temp_ch3 | temp_ch4);
}
static unsigned char sbox(unsigned char _ch)
{
 int j = 0,k = 0;
 int S0[4][4]={{1,0,3,2},{3,2,1,0},{0,2,1,3},{3,1,3,2}};
    int S1[4][4]={{0,1,2,3},{2,0,1,3},{3,0,1,0},{2,1,0,3}};

 unsigned char temp_ch1 = '/0',temp_ch2 = '/0';
 //左四位在S0中选,1 4位决定行 2 3位决定列
 j = (((_ch >> 6) & 2) | ((_ch >> 4) & 1));
 k = ((_ch >> 5) & 3);
 temp_ch1 = S0[j][k] << 2;
    //右四位在S1中选,1 4位决定行 2 3位决定列
 j = (((_ch >> 2) & 2) | (_ch & 1));
 k = ((_ch >> 1) & 3);
 temp_ch2 = S1[j][k];
 
 return (temp_ch1 | temp_ch2);
}
static unsigned char p4(unsigned char _ch)
{
 int i;
 unsigned char temp_ch = '/0';
 int p4[4] = {2,4,3,1};
    for(i = 0;i < 4;i++)
     temp_ch |= (((_ch >> (4-p4[i])) & 1) << (3-i));
   return temp_ch;
}
static unsigned char nip(unsigned char _ch)
{
    int i;
 int nip[8] = {4,1,3,5,7,2,8,6};
 unsigned char temp_ch = '/0';
    for(i = 0;i < 8;i++)//置换移位运算
  temp_ch |= (((_ch >> (8-nip[i])) & 1) << (7-i));
 
 return temp_ch;
}

 

//************************密钥涉及函数**************************
//密钥生成过程,包括P10置换函数,P8置换函数,shift移位函数//
//p10置换
static unsigned int p10(unsigned int key)
{
 int p10[10] = {3,5,2,7,4,10,1,9,8,6};
 int i,temp_key = 0;
    //移位置换操作
 for(i = 0;i < 10;i++)
  temp_key |= ((key >> (10-p10[i])) &1) << (9-i);

 return temp_key;
}
//P8置换
static unsigned char p8(unsigned int key)
{
  int i;
 key &= 0xff;
 int p8[8] = {4,1,5,2,6,3,8,7};
 unsigned char temp_key = '/0';
    for(i = 0;i < 8;i++)
  temp_key |= (key >> (8 - p8[i]) & 1) << (7-i);
   
   // printf("/n%x /n",temp_key);
    return temp_key;
}
//循环移位函数shift
//key输入的要移位2进制串
//key为十位密钥
static unsigned int _shift(unsigned int key,unsigned int round)
{
 unsigned int i;
    unsigned int left5 = 0,right5 = 0,temp_key = 0;
 for(i = 0;i < round;i++)
 {
  if((key >> 9) == 1)//如果高五位最高位为1
   left5 = (((key >> 5) & 15) << 1) | 1;//key右移五位,按位与01111,左移一位,或1                                        
  else if((key >> 9) == 0) //如果高五位最高位为0,左移四位,按位与01110
   left5 = (key >> 4) & 30;
   ;
     if(((key&0x10) >> 4) == 1)//如果低五位最高位为1
   right5 = ((key & 15) << 1) | 1;//按位与01111,结果左移一位,再或1
  else if(((key&0x10) >> 4) == 0)//如果低五位最高位为0
   right5 = key << 1;
            //right5 = (key & 15) * 2;//按位与01111,结果左移一位
        //高五位左移五位,或右五位,结果作为返回值
        temp_key = ((left5 << 5) | right5);
 }

 return temp_key;
}
int main(int argc,char **argv)
{
    time_t c_start,t_start, c_end,t_end;  
    c_start = clock();
       t_start = time(NULL) ;
    system("pause") ;
       c_end = clock();
    t_end = time(NULL) ;
    printf("The pause used %f ms by time()./n",difftime(c_end,c_start)) ;
       printf("The pause used %f s by clock()./n",difftime(t_end,t_start)) ;
 if(argc != 5)
 {
  printf("The number of argument is wrong ! /n");
     return -1;
 }
 if(argv[1][1] == 'e')
 {
        printf("%s /n",argv[2]);
  encr_sdes(argv[2],argv[3],argv[4]);
  printf("Finish the job of Encryption %s /n",argv[3]);
 }
 else if(argv[1][1] == 'd')
 {
        printf("%s",argv[2]);
  decr_sdes(argv[2],argv[3],argv[4]);
  printf("Finish the job of Decryption %s /n",argv[3]); 
 }
 else
  printf("Please check arguments you inputed ! /n");
 
 system("PAUSE");
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值