📄 function.h
字号:
#include<stdio.h>
#include<string.h>
#define NUM1 64
#define NUM2 56
#define NUM3 48
#define NUM4 32
#define NUM5 28
#define NUM6 16
#define MAXLEN 1024
#define MAX 8192
/*以下是关于DES算法中一些数据的定义*/
int key[NUM6][NUM3]; /*用来保存16个子密钥*/
int t[14],f[14]; /*t[],f[]用来保存游程中各数据串的个数*/
static const int IP1[NUM1] = {
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,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6
};
static const int IP2[NUM1] = {
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,
32, 0, 40, 8, 48, 16, 56, 24
};
static const int PC1[NUM2] = {
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
};
static const int PC2[NUM3] = {
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
};
static const int leftshift[NUM6] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
static const int S[8][64] = { /*真S盒*/
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, 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,
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
};
static const int S1[8][64] = { /*伪S盒*/
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,
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,
11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
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,
15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
6, 9,13, 4, 7,14, 1, 3,11, 0,12, 2, 5,10,15, 8,
1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
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,
13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
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,
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,
4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
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,
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,
13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2
};
/*选择运算E*/
static const int E[NUM3] = {
31, 0, 1, 2, 3, 4,
3, 4, 5, 6, 7, 8,
7, 8, 9,10,11,12,
11,12,13,14,15,16,
15,16,17,18,19,20,
19,20,21,22,23,24,
23,24,25,26,27,28,
27,28,29,30,31, 1
};
static const int P[NUM4] = {15, 6,19,20,28,11,27,16,
0,14,22,25, 4,17,30, 9,
1, 7,23,13,31,26, 2, 8,
18,12,29, 5,21,10, 3,24
};
int key_setup(int p[]); /*函数说明*/
void cryption(int p[],int k[],int judge);
void change1(char p[],int q[],int k);
void change2(char p[],int q[]);
void encrypt(int p[],int q[],int pq[],int judge);
void decrypt(int p[],int q[],int pq[]);
void HTB(char n,int *s1);
void traveral(int a[],int tra[],int k);
void DES(char *plaintext,char *ciphertext,char *deciphertext,int k)
{
int i,j,n,a,b;
char buf_text[8];
char ciphertext1[MAXLEN];
int plain[NUM1],cipher[NUM1],L[NUM4],R[NUM4],short_buf[NUM1];
int p_temp[NUM1],buf_temp[NUM1]; /*数组中间变量(用作暂存)*/
int R1[NUM4],L1[NUM4],cipher1[NUM1];
int yc[MAX],yc1[MAX]; /*保存加密后的0、1串*/
a=k/8;
b=k%8;
for(n=0;n<a;n++) /*先对前面的8的整数倍的字符串进行加密*/
{change1(plaintext+8*n,plain,8);
for(i=0;i<NUM1;i++)
p_temp[i]=*(plain+IP1[i]);
for(i=0;i<NUM4;i++)
{L[i]=p_temp[i];
R[i]=p_temp[i+NUM4];
}
for(i=0;i<NUM4;i++)
{L1[i]=L[i];
R1[i]=R[i];
}
encrypt(L1,R1,cipher1,0);
change2(ciphertext1+8*n,cipher1);
encrypt(L,R,cipher,1);
change2(ciphertext+8*n,cipher);
decrypt(R,L,plain);
change2(deciphertext+8*n,plain);
}
if(b!=0) /*如果存在短块,则进行相应处理*/
{for(i=NUM1-(8-b)*8,j=0;i<NUM1;i++,j++)
buf_temp[j]=cipher[i];
change1(plaintext+8*a,short_buf,b);
for(i=0,j=8*(8-b);j<NUM1;i++,j++)
buf_temp[j]=short_buf[i];
for(i=0;i<NUM1;i++)
p_temp[i]=*(buf_temp+IP1[i]);
for(i=0;i<NUM4;i++)
{L[i]=p_temp[i];
R[i]=p_temp[i+NUM4];
}
for(i=0;i<NUM4;i++)
{L1[i]=L[i];
R1[i]=R[i];
}
encrypt(L1,R1,cipher1,0);
change2(ciphertext1+8*a-(8-b),cipher1);
encrypt(L,R,cipher,1);
change2(ciphertext+8*a-(8-b),cipher);
decrypt(R,L,plain);
change2(buf_text,plain);
for(i=8-b,j=k-b;i<8;i++,j++)
deciphertext[j]=buf_text[i];
}
change1(ciphertext,yc,k);
traveral(yc,t,k*8);
change1(ciphertext1,yc1,k);
traveral(yc1,f,k*8);
}
/*用来将十六进制转换位二进制*/
void HTB(char n,int *s1)
{
int s[4]={0,0,0,0},i,j,k=0,g;
if(n>=48&&n<=57) g=(int)(n-48);
else {
if(n>64&&n<71) g=(int)(n-55);
else g=(int)(n-87);
}
i=g%2;
j=g/2;
s[3-k]=i;
while(j)
{
k++;
i=j%2;
j=j/2;
s[3-k]=i;
}
for(i=0;i<4;i++)
*(s1+i)=*(s+i);
}
/*用来计算0、1串中各游程的数目*/
void traveral(int a[],int tra[],int k)
{
int i;
for(i=0;i<k-2;i++)
{if(a[i]==0)
{tra[0]++;
if(a[i+1]==0)
{tra[2]++;
if(a[i+2]==0) tra[6]++;
else tra[7]++;
}
else
{tra[3]++;
if(a[i+2]==0) tra[8]++;
else tra[9]++;
}
}
else
{tra[1]++;
if(a[i+1]==0)
{tra[4]++;
if(a[i+2]==0) tra[10]++;
else tra[11]++;
}
else
{tra[5]++;
if(a[i+2]==0) tra[12]++;
else tra[13]++;
}
}
}
if(a[k-2]==0)
{tra[0]++;
if(a[MAX-1]==0)
{tra[0]++;
tra[2]++;
}
else
{tra[1]++;
tra[3]++;
}
}
else
{tra[1]++;
if(a[k-1]==0)
{tra[0]++;
tra[4]++;
}
else
{tra[1]++;
tra[5]++;
}
}
}
/*16轮加密函数(p为指向左边的32位串,q指向右边串,
pq指向密文串),通过变量judge来判断是用真S盒还是伪S盒进行加密*/
void encrypt(int p[],int q[],int pq[],int judge)
{
int R_temp[NUM4],temp[NUM1];
int i,j;
for(i=0;i<NUM6;i++) /*进行16轮的加密过程*/
{for(j=0;j<NUM4;j++)
R_temp[j]=q[j];
cryption(q,key[i],judge);
for(j=0;j<NUM4;j++)
{q[j]=q[j]^p[j];
p[j]=R_temp[j];
}
}
for(j=0;j<NUM4;j++)
{temp[j]=q[j];
temp[j+NUM4]=p[j];
}
for(i=0;i<NUM1;i++)
pq[i]=*(temp+IP2[i]);
}
/*解密函数*/
void decrypt(int p[],int q[],int pq[])
{
int R_temp[NUM4],temp[NUM1];
int i,j;
for(i=NUM6-1;i>=0;i--) /*进行16轮的解密过程*/
{for(j=0;j<NUM4;j++)
R_temp[j]=q[j];
cryption(q,key[i],1);
for(j=0;j<NUM4;j++)
{q[j]=q[j]^p[j];
p[j]=R_temp[j];
}
}
for(j=0;j<NUM4;j++)
{temp[j]=q[j];
temp[j+NUM4]=p[j];
}
for(i=0;i<NUM1;i++)
pq[i]=*(temp+IP2[i]);
}
/*密钥生成函数(并且执行弱密码检验)*/
int key_setup(int p[]) /*p[]为64位密钥的指针*/
{
int i,j,k,m,n,flag=1,flag1=0;
int C[NUM5],D[NUM5],C_temp[NUM5],D_temp[NUM5],key_temp[NUM2];
for(i=0;i<NUM5;i++)
{C[i]=*(p+PC1[i]);
D[i]=*(p+PC1[i+NUM5]);
}
for(i=0;i<(NUM5-1);i++)
{if(C[i]!=C[i+1]||D[i]!=D[i+1])
{flag=0;
break;
}
}
if(flag==1)
{
flag1=1;
return flag1;
}
else
for(i=0;i<NUM6;i++) /*进行16轮的子密钥的生成*/
{k=leftshift[i];
for(n=0;n<NUM5;n++)
{C_temp[n]=C[n];
D_temp[n]=D[n];
}
for(j=0;j<NUM5;j++)
{C[j]=C_temp[(j+k)%NUM5];
D[j]=D_temp[(j+k)%NUM5];
key_temp[j]=C[j];
key_temp[j+NUM5]=D[j];
}
for(m=0;m<NUM3;m++)
key[i][m]=*(key_temp+PC2[m]);
}
return flag1;
}
/*加密函数f(A,k),运算结果保存在p[]中,p[]为32位的输入,
k[]为48位的子密钥,通过judge来判断是用真S盒还是伪s盒来处理*/
void cryption(int p[],int k[],int judge)
{
int i,j,m,n,flag,a;
int l=0,b=0;
int p1[NUM3],q[6],q1[4],temp[32];
for(i=0;i<NUM3;i++)
p1[i]=*(p+E[i]);
for(i=0;i<NUM3;i++)
p1[i]=p1[i]^k[i];
for(i=0,flag=0;i<NUM3;flag++)
{
for(j=0;j<6;j++,i++)
q[j]=p1[i];
m=q[0]*2+q[5];
n=q[1]*8+q[2]*4+q[3]*2+q[4];
if(judge==1) a=S[flag][m*16+n];
else a=S1[flag][m*16+n];
q1[l++]=a/8;
q1[l++]=(a/4)%2;
q1[l++]=(a/2)%2;
q1[l]=a%2;
l=0;
for(n=0;n<4;n++,b++)
{temp[b]=q1[n];}
}
for(i=0;i<NUM4;i++)
p[i]=*(temp+P[i]);
}
/*将字符串转换成对应的1、0串,k为字符串的字符个数*/
void change1(char p[],int q[],int k)
{
int i,j;
for(i=0,j=0;i<k;i++)
{
q[j++]=(p[i]&0x80)>>7;
q[j++]=(p[i]&0x40)>>6;
q[j++]=(p[i]&0x20)>>5;
q[j++]=(p[i]&0x10)>>4;
q[j++]=(p[i]&0x08)>>3;
q[j++]=(p[i]&0x04)>>2;
q[j++]=(p[i]&0x02)>>1;
q[j++]=(p[i]&0x01);
}
}
/*将64bit位的1、0串转换成对应的8个字符串*/
void change2(char p[],int q[])
{
int i,j;
for(i=0,j=0;i<8;i++)
{
p[i]=(q[j++]&0x01)<<7;
p[i]+=(q[j++]&0x01)<<6;
p[i]+=(q[j++]&0x01)<<5;
p[i]+=(q[j++]&0x01)<<4;
p[i]+=(q[j++]&0x01)<<3;
p[i]+=(q[j++]&0x01)<<2;
p[i]+=(q[j++]&0x01)<<1;
p[i]+=(q[j++]&0x01);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -