📄 des1.h
字号:
/*DES 算法c语言实现函数 编写者 王晓峰 2002年11月,
这是我的一个练习函数,在此函数的编写调试过程中我发现一个错误:
在IP_1变换过程中IP_1变换表存在错误,我手中的几本书上提供的变换表如下:
int IP_1[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}; 此IP_1变换换位表错误!!
但调试不能通过,后我通过手工反演计算发现将此表做如下调整可得正确结果,即将1、2,3、4,5、6,7、8列对调。
现将调整后结果给出如下:
int IP_1[64]={ 8,40,16,48,24,56,32,64,
7,39,15,47,23,55,31,63,
6,38,14,46,22,54,30,62,
5,37,13,45,21,53,29,61,
4,36,12,44,20,52,28,60,
3,35,11,43,19,51,27,59,
2,34,10,42,18,50,26,58,
1,33, 9,41,17,49,25,57};
王晓峰
2002.11.25
*/
void BittoByte(char p[8],char Data[64])
/*
将原始数据位扩展为字节,
char p[8] 原始8字节数组,
char data[64]扩展目标数组,内容为0或1,
char temp 临时字符,
int i 工作变量字符数组下标,
int j 工作变量i所指字符的位标。
*/
{
char temp;
int i,j;
for(i=0;i<64;i++)
{
j=i%8;
temp=p[i/8];
temp=temp<<j;
Data[i]=temp>>7;
if (Data[i]==-1) Data[i]=1;
}
}
void BittoByte_48(char p[6],char Data[48])
/*
将原始数据位扩展为字节,
char p[8] 原始8字节数组,
char data[64]扩展目标数组,内容为0或1,
char temp 临时字符,
int i 工作变量字符数组下标,
int j 工作变量i所指字符的位标。
*/
{
char temp;
int i,j;
for(i=0;i<48;i++)
{
j=i%8;
temp=p[i/8];
temp=temp<<j;
Data[i]=temp>>7;
if (Data[i]==-1) Data[i]=1;
}
}
void BytetoBit(char p[8],char Data[64])
/*
将以64字节表示的位组压缩为8字节数组,
char p[8] 目标8字节数组,
char Data[64]原始64位比特位组,
int i 工作变量位组下标,
*/
{
int i;
for(i=0;i<8;i++)
p[i]=0;
for(i=0;i<64;i++)
{
p[i/8]=p[i/8]+Data[i];
if(i%8!=7) p[i/8]=p[i/8]*2;
}
}
void IntitalPermutation(char Data[64],char L[32],char R[32])
/*
初始排列函数,
int IP[64] 初始排列法,0-63位,使用时 IP[i]-1,
char Data[64]明文代码, 0-63位,
char L[32] IP排列后前32位代码 0-31位,
char R[32] IP排列后后32位代码 0-31位,
int i 工作变量.
*/
{
int IP[64]={58,50,42,34,26,18,10,02,
60,52,44,36,28,20,12,04,
62,54,46,38,30,22,14,06,
64,56,48,40,32,24,16, 8,
57,49,41,33,25,17, 9,01,
59,51,43,35,27,19,11,03,
61,53,45,37,29,21,13,05,
63,55,47,39,31,23,15,07};
int i;
for(i=0;i<64;i++)
if (i<32) L[i]=Data[IP[i]-1];
else R[i-32]=Data[IP[i]-1];
}
void Expand(char Data1[32],char Data2[48])
/*
扩展转换 32位->48位,
char Data1[32]原始32位代码,
char Data2[48]扩展后的48位代码,
int i 工作变量 Data1 各位的下标,
int Exp[48] 扩展置换表,使用时Exp[i]-1.
*/
{
int Exp[48]={ 32,01,02,03,04,05,
04,05,06,07, 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,01};
int i;
for(i=0;i<48;i++)
Data2[i]=Data1[Exp[i]-1];
}
void Compressedencoding(char Data1[48],char Data2 [32])
/*压缩48位->32位,
char Data1[48] 输入48位位组,
char Data2[32] 输出32位位组,
char string[4] 4字节字符数组存放中间结果,
char temp 临时工作变量,
int S[8][4][16] S盒8组每组4行16列,
int hang[8] S盒的行号,
int lei[8] S盒的列号,
int i 临时工作变量,
int j 临时工作变量.
*/
{
char string[4];
char temp;
int hang[8],lei[8];
int i,j;
int S[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},
{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},
{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},
{ 7,13,14, 3, 0, 6, 9,10, 1, 2, 8,05,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},
{ 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},
{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},
{ 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},
{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},
};
for(i=0;i<8;i++)
{
hang[i]=Data1[i*6]*2+Data1[i*6+5];
lei[i]=Data1[i*6+1]*8+Data1[i*6+2]*4+Data1[i*6+3]*2+Data1[i*6+4];
}
for(i=0;i<4;i++)
{
string[i]=(S[i*2][hang[i*2]][lei[i*2]]*16+S[i*2+1][hang[i*2+1]][lei[i*2+1]]);
}
for(i=0;i<32;i++)
{
j=i%8;
temp=string[i/8];
temp=temp<<j;
Data2[i]=temp>>7;
if (Data2[i]==-1) Data2[i]=1;
}
}
void Pchang(char Data1[32],char Data2[32])
/* P排列换位表变换,
char Data1[32] 输入32位位组,
char Data2[32] 输出32位位组,
int p[32] 换位表使用时p[i]-1,
int i 临时工作变量。
*/
{
int p[32]={ 16,07,20,21,
29,12,28,17,
01,15,23,26,
05,18,31,10,
02, 8,24,14,
32,27,03, 9,
19,13,30,06,
22,11,04,25};
int i;
for(i=0;i<32;i++)
Data2[i]=Data1[p[i]-1];
}
void Intitalpermutation_1(char Data[64],char L[32],char R[32])
/* Ip_1变换,
char Data[64]输出64位组,
char L[32] 输入的前半部32位位组,
char R[32] 输入的后半部32位位组,
char temp[64]临时工作数组,
int IP_1[64] IP_1换位表,使用时IP_1[i]-1,
int i 临时工作变量。
*/
{
/*int IP_1[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};此IP_1变换换位表错误!!!!!!!!! */
int IP_1[64]={ 8,40,16,48,24,56,32,64,
7,39,15,47,23,55,31,63,
6,38,14,46,22,54,30,62,
5,37,13,45,21,53,29,61,
4,36,12,44,20,52,28,60,
3,35,11,43,19,51,27,59,
2,34,10,42,18,50,26,58,
1,33, 9,41,17,49,25,57};
char temp[64];
int i;
for(i=0;i<64;i++)
{
if(i<32) temp[i]=L[i];
else temp[i]=R[i-32];
}
for(i=0;i<64;i++)
Data[i]=temp[IP_1[i]-1];
}
void Mishi(char Data[64],char Mishi[16][48])
/*生成16个48位密钥,
char Data[64] 原始64位密钥明文,
char Mishi[16][48] 存放生成的16个48位子密钥,
char C[28],D[28] 两个28位循环左移位组,
char temp[56] 临时工作数组,存放56位中间结果位组,
char temp_c 临时工作变量,
char temp_d 临时工作变量,
int PC_1_c[28] 原始64位密钥明文去掉校验位后的前28位,使用时PC_2[i]-1,
int PC_1_d[28] 原始64位密钥明文去掉校验位后的后28位,使用时PC_2[i]-1,
int PC_2[48] 56位中48位子集换位表,使用时PC_2[j]-1,
int LS[16] 16次循环左移位数表,
int i,j,k 临时工作变量,
*/
{
int PC_1_c[28]={ 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};
int PC_1_d[28]={ 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 LS[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
int PC_2[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};
char C[28],D[28];
char temp[56];
char temp_c;
char temp_d;
int i,j,k;
for(i=0;i<28;i++)
{
C[i]=Data[PC_1_c[i]-1];
D[i]=Data[PC_1_d[i]-1];
}
for(i=0;i<16;i++)
{
for(j=LS[i];j>0;j--) /*循环左移*/
{
temp_c=C[0];
temp_d=D[0];
for(k=0;k<27;k++) /*循环左移1位*/
{
C[k]=C[k+1];
D[k]=D[k+1];
}
C[27]=temp_c;
D[27]=temp_d;
}
for(j=0;j<56;j++)
{
if(j<28)
temp[j]=C[j];
else temp[j]=D[j-28];
}
for(j=0;j<48;j++)
{
Mishi[i][j]=temp[PC_2[j]-1];
}
}
}
void Des(char string1[8],char string2[8],int flag,int flag2)
/*DES 标准算法加密解密函数,
char string1[8] 输入的8字节明文或密文,
char string2[8] 输入的8字节原始密钥,
char Data1[64] 扩展的64位明文或密文位组,
char Data2[64] 扩展的64位原始密钥位组,
char Miyao[16][48] 16个子密钥的48位位组,
char L[32],R[32] 明文或密文的前32位位组和后32位位组,
char Expand_data[48] 由32位扩展而成的48位位组,
char temp1[32] 临时工作32位位组,
char temp2[32] 临时工作32位位组,
int flag 加解密标志:flag==0为加密,反之为解密,
int flag2 是否重新计算子密钥,flag==0为计算,反之为不计算.
ing i,j 临时工作变量。
*/
{
char Data1[64];
char Data2[64];
static char Miyao[16][48];
char L[32],R[32];
char Expand_data[48];
char temp1[32];
char temp2[32];
int i,j;
BittoByte(string1,Data1); /*比特至字节的转换*/
BittoByte(string2,Data2); /*比特至字节的转换*/
IntitalPermutation(Data1,L,R); /*IP变换*/
if (flag2==0) Mishi(Data2,Miyao); /*密匙生成*/
if(flag==0) /*加密过程*/
{
for(i=0;i<16;i++)
{
Expand(R,Expand_data); /*右半部32位扩展为48位*/
for(j=0;j<48;j++) /*与子密钥异或*/
{
Expand_data[j]=Expand_data[j]^Miyao[i][j];
}
Compressedencoding(Expand_data,temp1); /*压缩48位为32位*/
Pchang(temp1,temp2); /*P变换*/
for(j=0;j<32;j++) /*与左半部异或*/
{
temp2[j]=temp2[j]^L[j];
}
for(j=0;j<32;j++) /*右半部放入左半部,右半部存入上步异或结果*/
{
L[j]=R[j];
R[j]=temp2[j];
}
}
Intitalpermutation_1(Data1,L,R); /*IP-1变换*/
BytetoBit(string1,Data1); /*字节转换为比特*/
}
else /*解密过程*/
{
for(i=15;i>-1;i--)
{
Expand(R,Expand_data); /*右半部32位扩展为48位*/
for(j=0;j<48;j++) /*与子密钥异或*/
{
Expand_data[j]=Expand_data[j]^Miyao[i][j];
}
Compressedencoding(Expand_data,temp1); /*压缩48位为32位*/
Pchang(temp1,temp2); /*P变换*/
for(j=0;j<32;j++) /*与左半部异或*/
{
temp2[j]=temp2[j]^L[j];
}
for(j=0;j<32;j++) /*右半部放入左半部,右半部存入上步异或结果*/
{
L[j]=R[j];
R[j]=temp2[j];
}
}
Intitalpermutation_1(Data1,L,R); /*IP-1变换*/
BytetoBit(string1,Data1); /*字节转换为比特*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -