奋战了好长时间,终于写出了一个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;
}