int
DES(
unsigned
char
*
bufferin,
unsigned
char
*
bufferout,
unsigned
char
*
key,
long
mode)
{
//
密钥变换为56字节(去掉校验位)
static
unsigned
char
pc1[
56
]
=
{
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
};
//
56字节变换为48 字节(数据压缩)
static
unsigned
char
pc2[
48
]
=
{
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
};
//
32字节变换为48字节(数据扩展)
static
unsigned
char
exp[
48
]
=
{
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
,
0
};
//
64位数据IP(Initial Permutation)变换表
static
unsigned
char
ip[
64
]
=
{
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
};
//
数据逆置换(Final Permutation)
static
unsigned
char
ip_1[
64
]
=
{
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
};
//
Permutation P
static
unsigned
char
pp[
32
]
=
{
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
};
/*
INITIALIZE THE TABLES
*/
/*
Table - s1
*/
static
unsigned
char
s1[
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
};
/*
Table - s2
*/
static
unsigned
char
s2[
4
][
16
]
=
{
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
};
/*
Table - s3
*/
static
unsigned
char
s3[
4
][
16
]
=
{
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
};
/*
Table - s4
*/
static
unsigned
char
s4[
4
][
16
]
=
{
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
};
/*
Table - s5
*/
static
unsigned
char
s5[
4
][
16
]
=
{
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
};
/*
Table - s6
*/
static
unsigned
char
s6[
4
][
16
]
=
{
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
};
/*
Table - s7
*/
static
unsigned
char
s7[
4
][
16
]
=
{
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
};
/*
Table - s8
*/
static
unsigned
char
s8[
4
][
16
]
=
{
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
unsigned
char
totrot[]
=
{
1
,
2
,
4
,
6
,
8
,
10
,
12
,
14
,
15
,
17
,
19
,
21
,
23
,
25
,
27
,
28
};
/*
----------------------------------------------
*/
//
long mode = 1;
//
模式,1:加密,2:解密
//
unsigned char bufferin[9], bufferout[9];
//
明文,密文
/*
----------------------------------------------
*/
long
i, j, k;
long
rotshift;
//
密钥移位次数
//
long keylen, buflen;
//
密钥长度,明文长度
unsigned
char
keybuf[
65
];
//
密钥,密钥64字节缓冲区
unsigned
char
keyreal[
57
], keys[
17
][
49
];
//
实际使用56字节密钥,48字节密钥数组
unsigned
char
srcbuf[
65
], dstbuf[
65
];
//
明文,密文64字节缓冲区
unsigned
char
L[
17
][
33
], R[
17
][
33
], LR[
65
], RL[
65
];
//
加密时临时数据左右两部分
unsigned
char
E[
17
][
49
];
//
R数组的扩展数据
unsigned
char
B[
9
][
7
], BB[
33
], P[
33
];
//
E和K异或后的缓冲数组
unsigned
char
C[
17
][
29
], D[
17
][
29
], CD[
57
];
//
56字节密钥的左右两部分
unsigned
char
temp1, temp2, m, n, x;
//
1.变换密钥
//
密钥不足8字节则用0补足(或自定义)
//
keylen = strlen((const char*)key);
//
if(keylen<8)
//
memset(key+keylen, 0, (8-keylen));
//
将8字节密钥转换为64字节字串
for
(i
=
0
;i
<
8
;i
++
)
{
j
=
*
(key
+
i);
keybuf[
8
*
i]
=
(j
/
128
)
%
2
;
keybuf[
8
*
i
+
1
]
=
(j
/
64
)
%
2
;
keybuf[
8
*
i
+
2
]
=
(j
/
32
)
%
2
;
keybuf[
8
*
i
+
3
]
=
(j
/
16
)
%
2
;
keybuf[
8
*
i
+
4
]
=
(j
/
8
)
%
2
;
keybuf[
8
*
i
+
5
]
=
(j
/
4
)
%
2
;
keybuf[
8
*
i
+
6
]
=
(j
/
2
)
%
2
;
keybuf[
8
*
i
+
7
]
=
(j
/
1
)
%
2
;
}
//
根据pc1进行变换成56字节,去掉奇偶校验位
for
(i
=
0
;i
<
56
;i
++
)
{
keyreal[i]
=
keybuf[pc1[i]];
}
//
将56字节密钥分为左右两部分C[0],D[0]
for
(i
=
0
;i
<
28
;i
++
)
{
C[
0
][i]
=
keyreal[i];
D[
0
][i]
=
keyreal[i
+
28
];
}
//
循环16次(i从1开始)
for
(i
=
1
;i
<
17
;i
++
)
{
//
根据加密或解密确定密钥顺序
if
(mode)
//
加密
rotshift
=
totrot[i
-
1
];
else
//
解密
rotshift
=
totrot[
16
-
i];
//
1)左移固定位数得到C[i]和D[i];
for
(j
=
0
;j
<
28
;j
++
)
{
C[i][j]
=
C[
0
][j];
D[i][j]
=
D[
0
][j];
}
for
(j
=
0
;j
<
rotshift;j
++
)
{
temp1
=
C[i][
0
];
temp2
=
D[i][
0
];
for
(k
=
0
;k
<
27
;k
++
)
{
C[i][k]
=
C[i][k
+
1
];
D[i][k]
=
D[i][k
+
1
];
}
C[i][
27
]
=
temp1;
D[i][
27
]
=
temp2;
}
//
2)将C[i]D[i]用pc2化简为48位k[i];
for
(j
=
0
;j
<
28
;j
++
)
{
CD[j]
=
C[i][j];
CD[j
+
28
]
=
D[i][j];
}
for
(j
=
0
;j
<
48
;j
++
)
{
keys[i][j]
=
CD[pc2[j]];
}
}
//
2.数据处理
//
若明文不足8字节则补0(或自定义)
//
buflen = strlen((const char*)bufferin);
//
if(buflen<8)
//
memset(bufferin+buflen, 0, (8-buflen));
//
将8字节数据转换为64字节字串
for
(i
=
0
;i
<
8
;i
++
)
{
j
=
*
(bufferin
+
i);
srcbuf[i
*
8
]
=
(j
/
128
)
%
2
;
srcbuf[i
*
8
+
1
]
=
(j
/
64
)
%
2
;
srcbuf[i
*
8
+
2
]
=
(j
/
32
)
%
2
;
srcbuf[i
*
8
+
3
]
=
(j
/
16
)
%
2
;
srcbuf[i
*
8
+
4
]
=
(j
/
8
)
%
2
;
srcbuf[i
*
8
+
5
]
=
(j
/
4
)
%
2
;
srcbuf[i
*
8
+
6
]
=
(j
/
2
)
%
2
;
srcbuf[i
*
8
+
7
]
=
(j
/
1
)
%
2
;
}
//
将srcbuf按ip进行变换
for
(i
=
0
;i
<
64
;i
++
)
LR[i]
=
srcbuf[ip[i]];
//
将64字节数据转换为两部分L[0],R[0]
for
(i
=
0
;i
<
32
;i
++
)
{
L[
0
][i]
=
LR[i];
R[
0
][i]
=
LR[i
+
32
];
}
//
循环16次(i从1开始),用密钥加密数据
for
(i
=
1
;i
<
17
;i
++
)
{
//
1)将32位的R[i-1]按exp扩展为48位的E[i-1];
for
(j
=
0
;j
<
48
;j
++
)
{
E[i
-
1
][j]
=
R[i
-
1
][exp[j]];
}
//
2)异或E[i-1]和K[i];
for
(j
=
0
;j
<
48
;j
++
)
{
keys[i][j]
=
keys[i][j]
^
E[i
-
1
][j];
}
//
3)将异或结果分为8个6位长的部分B[8]
for
(j
=
0
;j
<
8
;j
++
)
{
B[j][
0
]
=
keys[i][j
*
6
];
B[j][
1
]
=
keys[i][j
*
6
+
1
];
B[j][
2
]
=
keys[i][j
*
6
+
2
];
B[j][
3
]
=
keys[i][j
*
6
+
3
];
B[j][
4
]
=
keys[i][j
*
6
+
4
];
B[j][
5
]
=
keys[i][j
*
6
+
5
];
}
//
4)循环用S表替换(j从1开始)
for
(j
=
0
;j
<
8
;j
++
)
{
//
a)B[j]第1位和第6位组合为M,作为S[j]的行号
m
=
2
*
B[j][
0
]
+
B[j][
5
];
//
b)B[j]第2到5位组合为N,作为S[j]的列号
n
=
2
*
(
2
*
(
2
*
B[j][
1
]
+
B[j][
2
])
+
B[j][
3
])
+
B[j][
4
];
//
c)用S[j][M][N]来取代B[j]
switch
(j)
{
case
0
:
x
=
s1[m][n];
break
;
case
1
:
x
=
s2[m][n];
break
;
case
2
:
x
=
s3[m][n];
break
;
case
3
:
x
=
s4[m][n];
break
;
case
4
:
x
=
s5[m][n];
break
;
case
5
:
x
=
s6[m][n];
break
;
case
6
:
x
=
s7[m][n];
break
;
case
7
:
x
=
s8[m][n];
break
;
}
BB[j
*
4
]
=
(x
/
8
)
%
2
;
BB[j
*
4
+
1
]
=
(x
/
4
)
%
2
;
BB[j
*
4
+
2
]
=
(x
/
2
)
%
2
;
BB[j
*
4
+
3
]
=
(x
/
1
)
%
2
;
}
//
5)将B[1]到B[8]按P组合得到p
for
(j
=
0
;j
<
32
;j
++
)
{
P[j]
=
BB[pp[j]];
}
//
6)R[i] = p xor L[i-1];L[i] = R[i-1];
for
(j
=
0
;j
<
32
;j
++
)
{
R[i][j]
=
P[j]
^
L[i
-
1
][j];
L[i][j]
=
R[i
-
1
][j];
}
}
//
3.组合变换后的R[16]L[16]按ip_1变换得到最后结果
for
(i
=
0
;i
<
32
;i
++
)
{
RL[i]
=
R[
16
][i];
RL[i
+
32
]
=
L[
16
][i];
}
for
(i
=
0
;i
<
64
;i
++
)
{
dstbuf[i]
=
RL[ip_1[i]];
}
//
将64字节数据转换为8字节
for
(i
=
0
; i
<
8
; i
++
)
{
*
(bufferout
+
i)
=
0x00
;
for
(k
=
0
; k
<
7
; k
++
)
*
(bufferout
+
i)
=
((
*
(bufferout
+
i))
+
dstbuf[
8
*
i
+
k])
*
2
;
*
(bufferout
+
i)
=
*
(bufferout
+
i)
+
dstbuf[
8
*
i
+
7
];
}
return
0
;
}