#include<stdio.h>
#include<string.h>
#include <stdlib.h>
//初始值换IP
int ipreplacement_1 [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
};
//初始值换IP-1
int ipreplacement_2 [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
};
//扩展变换E
int e_change[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
};
//P变换
int p_exchange[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
};
unsigned char sbox[8][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}
},//s1
{
{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}
},//s2
{
{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}
},//s3
{
{ 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}
},//s4
{
{ 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}
},//s5
{
{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}
},//s6
{
{ 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}
},//s7
{
{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}
}//s8
};
//密钥PC1置换表
int key_table1[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
};
//密钥PC2置换表
int key_table2[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 keys_LS[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};//对左移次数的规定
int keys_RS[16]={0,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};//对右移次数的规定
void des_encrypt(char *,char *,unsigned char*); //des加密的主程序
void group_encrypt(unsigned char* plaintext,unsigned char *ciphertext,unsigned char *key);//对分组进行加密
void des_decrypt(char *,char*,unsigned char*); //des解密的主程序
void group_decrypt(unsigned char *plaintext,unsigned char *ciphertext,unsigned char *key);//对分组进行解密
void keys_lshift(unsigned char *keys,int count);
void keys_rshift(unsigned char *keys,int count);
void CharToBit(unsigned char *CharString,unsigned char *BitString);
void BitToChar(unsigned char* BitString,unsigned char *CharString);
void round_function(unsigned char * text_l,unsigned char *text_r,unsigned char *subkeys);
unsigned char ebox_result[48];//扩展变换e结果
unsigned char sbox_result1[32];//s盒压缩变换结果
unsigned char p_result[32];//p变换结果
unsigned char sbox_result[8];//s盒分别取出的8次数据
void main(int argc,char *argv[])
{
if(argc == 5)
{
if ( strcmp(argv[1],"-e") == 0) //对文件进行加密
{
unsigned char keys[8] = {0,0,0,0,0,0,0,0};//防止输入密钥长度小于8
memcpy(keys,argv[2],strlen(argv[2]));
des_encrypt(argv[3],argv[4],keys);
}
if (strcmp(argv[1] ,"-d") == 0) //对文件进行解密
{
unsigned char keys[8] = {0,0,0,0,0,0,0,0};
memcpy(keys,argv[2],strlen(argv[2]));
des_decrypt(argv[3],argv[4],keys);
}
}
else if(argc == 2) //使用帮助
{
if (strcmp(argv[1],"-?") == 0)
{
printf("本程序使用的是des加解密算法。\n参数输入格式为:des -e f:/xxx.xxx e:/xxx.xxx\n");
}
else
printf("参数输入有误!");
return;
}
else
printf("参数输入有误!");
return;
}
void des_encrypt(char *inputfilepath,char *outputfilepath,unsigned char *keys)
{
FILE *inputfile,*outputfile; //文件指针
unsigned char plaintext[8],ciphertext[8],key[8];
long filelength,round; //文件的长度和使用des的次数
int rest;
memset(key,'x',sizeof(char) *8);
memcpy(key,keys,8); //填充密钥
inputfile = fopen(inputfilepath,"rb");
if(inputfile == NULL)
{
printf("文件的输入路径有误!");
return;
}
outputfile = fopen(outputfilepath,"wb");
if(outputfile == NULL)
{
printf("文件的输出路径有误!");
return;
}
fseek(inputfile,0L,SEEK_END); //把指针移至文件末尾
filelength = ftell(inputfile); //计算出文件的长度
rewind(inputfile); //把指针重新定位到文件头
round = filelength / 8;
rest = filelength % 8;
printf("文件加密轮数:%d 多余字节数:%d",round,rest);
for (int i = 0 ; i< round ;i++) //进行分组加密
{
fread(plaintext,sizeof(unsigned char),8,inputfile);
group_encrypt(plaintext,ciphertext,key);
fwrite(ciphertext,sizeof(unsigned char),8,outputfile);
}
if (rest) //如果明文大小不是8个字节的倍数进行特殊处理
{
fread(plaintext,sizeof(unsigned char),rest,inputfile);
memset(plaintext + rest,'x', 8- rest); //把不足8个字节的部分用x填充
group_encrypt(plaintext,ciphertext,key);
fwrite(ciphertext,sizeof(unsigned char),8,outputfile);
fputc(rest,outputfile);
//fwrite(&rest,sizeof(int),1,outputfile);
}
fclose(inputfile);
fclose(outputfile); //分别关闭文件
}
void des_decrypt(char *inputfilepath,char *outputfilepath,unsigned char *keys)
{
FILE *inputfile,*outputfile; //文件指针
unsigned char plaintext[8],ciphertext[8],key[8];
long filelength,round; //文件的长度和使用des的次数
int rest;
memset(key,'x',sizeof(char) *8);
memcpy(key,keys,8); //填充密钥
inputfi