时间:2026-03-24 21:46
人气:
作者:admin
编程实现DES的加密和解密算法,对明文“0x0123456789ABCDEF”进行加密,采用密钥“0x133457799BBCDFF1”,输出每一轮的加密结果和轮密钥,并对密文进行解密,输出解密后的结果。

DES算法详细介绍我就不展开了,但是简略的过程如上。同样,有需要的读者适当考虑读全英文文献[1],或者利用各个社区进行系统的学习。
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char Byte;
typedef unsigned long long Bytes;
// 为Bytes定义Permutate函数
Bytes PermutateBytes(Bytes a, const int b[], int m, int n) {
Bytes c = 0;
for (int i = 0; i < n; i++) {
c = (c << 1) | ((a >> (m - b[i] - 1)) & 1);
}
return c;
}
// 为Byte定义Permutate函数
Byte PermutateByte(Byte a, const Byte b[], int m, int n) {
Byte c = 0;
for (int i = 0; i < n; i++) {
c = (c << 1) | ((a >> (m - b[i] - 1)) & 1);
}
return c;
}
// 交换两个Bytes类型的值
void swap(Bytes *a, Bytes *b) {
Bytes temp = *a;
*a = *b;
*b = temp;
}
Bytes IP(Bytes a) {
static int 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
};
return PermutateBytes(a, ip, 64, 64);
}
Bytes FP(Bytes a) {
static int fp[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
};
return PermutateBytes(a, fp, 64, 64);
}
Bytes PC1(Bytes key) {
static int pc1_l[28] = {
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
};
static int pc1_r[28] = {
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
};
return (PermutateBytes(key, pc1_l, 64, 28) << 28) | PermutateBytes(key, pc1_r, 64, 28);
}
Bytes PC2(Bytes key) {
static int 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
};
return PermutateBytes(key, pc2, 56, 48);
}
Bytes Rotate(Bytes a, int n) {
for (int i = 0; i < n; i++)
a = (a << 1 | (a >> 27 & 1)) & ((1 << 28) - 1);
return a;
}
void Keygen(Bytes key, Bytes keys[]) {
key = PC1(key);
Bytes l = key >> 28;
Bytes r = key ^ (l << 28);
int offset[16] = {
1, 1, 2, 2, 2, 2, 2, 2,
1, 2, 2, 2, 2, 2, 2, 1
};
for (int i = 0; i < 16; i++) {
l = Rotate(l, offset[i]);
r = Rotate(r, offset[i]);
keys[i] = PC2((l << 28) | r);
}
}
Bytes S(Bytes a) {
static Byte s_box[8][64] = {
{
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
}
};
Bytes res = 0;
static Byte p[6] = {0, 5, 1, 2, 3, 4};
for (int i = 0; i < 8; i++) {
Byte b = (a >> ((7 - i) * 6)) & ((1 << 6) - 1);
b = PermutateByte(b, p, 6, 6);
res = (res << 4) | s_box[i][b];
}
return res;
}
Bytes P(Bytes a) {
static int p[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
};
return PermutateBytes(a, p, 32, 32);
}
Bytes Expand(Bytes a) {
static int e[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
};
return PermutateBytes(a, e, 32, 48);
}
Bytes Round(Bytes a, Bytes subkey) {
Bytes t = Expand(a) ^ subkey;
t = S(t);
t = P(t);
return t;
}
Bytes Feistel(Bytes a, Bytes subkey) {
Bytes l = a >> 32;
Bytes r = a ^ (l << 32);
return (r << 32) | (l ^ Round(r, subkey));
}
Bytes DES(Bytes m, Bytes key, int decrypt, int round) {
Bytes keys[16] = {0};
Keygen(key, keys);
if (decrypt) {
for (int i = 0; i < 8; i++)
swap(&keys[i], &keys[15 - i]);
}
Bytes c = IP(m);
for (int i = 0; i < round; i++)
c = Feistel(c, keys[i]);
Bytes l = c >> 32;
Bytes r = c ^ (l << 32);
return FP((r << 32) | l);
}
Bytes Encrypt(Bytes m, int round) {
return DES(m, 0xcafababedeadbeafULL, 0, round);
}
void test() {
printf("Test rotate: ");
if (Rotate(167772165, 2) == 134217750) {
printf("OK.\n");
} else {
printf("GG!\n");
}
printf("Test IP: ");
if (IP(81985529216486895ULL) == 14699974583363760298ULL) {
printf("OK.\n");
} else {
printf("GG!\n");
}
printf("Test PC1: ");
if (PC1(1383827165325090801ULL) == 67779029043144591ULL) {
printf("OK.\n");
} else {
printf("GG!\n");
}
printf("Test keygen: ");
Bytes keys[16] = {0};
Keygen(1383827165325090801ULL, keys);
if (keys[15] == 223465186400245ULL) {
printf("OK.\n");
} else {
printf("GG!\n");
}
printf("Test S box: ");
if (S(178261171038007ULL) == 3725222752ULL) {
printf("OK.\n");
} else {
printf("GG!\n");
}
printf("Test round: ");
if (Round(3707429454ULL, 141493528337059ULL) == 3207079049ULL) {
printf("OK.\n");
} else {
printf("GG!\n");
}
}
int main() {
test();
Bytes m = 0x0123456789ABCDEF;
Bytes k = 0x133457799BBCDFF1;
// 生成轮密钥
Bytes round_keys[16];
Keygen(k, round_keys);
// 执行加密过程并输出每一轮的加密结果和轮密钥
Bytes d = m;
printf("Round 0 - Input: %016llx\n", d);
for (int i = 0; i < 16; i++) {
d = DES(d, round_keys[i], 0, i + 1);
printf("Round %d - Output: %016llx, Round Key: %016llx\n", i + 1, d, round_keys[i]);
}
Bytes c = DES(m, k, 0, 16);
printf("%016llx\n", c);
printf("%016llx\n", DES(c, k, 1, 16));
return 0;
}

简单转换为Python了,但是本质上还是C语言的思维在发挥作用。
#!/usr/bin/env python3
"""
DES加密算法的Python实现
基于C代码转换,包含完整的置换、S盒、密钥生成和Feistel网络
"""
# 类型别名
Byte = int
Bytes = int
# 通用置换函数(用于任意位数)
def permutate_bytes(a: Bytes, table: list, m: int, n: int) -> Bytes:
"""
根据置换表从输入a中提取位,生成新值
a: 输入整数
table: 置换表,元素为源位索引(0-based,从最高位开始计数)
m: 输入位数
n: 输出位数
"""
c = 0
for i in range(n):
# 获取第table[i]位的值(从最高位算起)
bit = (a >> (m - table[i] - 1)) & 1
c = (c << 1) | bit
return c
# 字节置换(用于6位输入/输出,但可通用)
def permutate_byte(a: Byte, table: list, m: int, n: int) -> Byte:
return permutate_bytes(a, table, m, n)
# 交换两个Bytes值
def swap(a: Bytes, b: Bytes) -> tuple:
return b, a
# ---------- 置换表 ----------
IP_TABLE = [
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
]
FP_TABLE = [
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
]
PC1_L = [
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
]
PC1_R = [
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
]
PC2_TABLE = [
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
]
P_TABLE = [
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
]
E_TABLE = [
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
]
# S盒
S_BOX = [
[ # S1
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
],
[ # S2
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
],
[ # S3
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
],
[ # S4
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
],
[ # S5
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
],
[ # S6
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
],
[ # S7
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
],
[ # S8
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
]
]
# S盒输出前的位重排(固定)
S_P = [0, 5, 1, 2, 3, 4]
# ---------- DES基本函数 ----------
def ip(a: Bytes) -> Bytes:
"""初始置换"""
return permutate_bytes(a, IP_TABLE, 64, 64)
def fp(a: Bytes) -> Bytes:
"""最终逆置换"""
return permutate_bytes(a, FP_TABLE, 64, 64)
def pc1(key: Bytes) -> Bytes:
"""密钥置换PC1,输出56位"""
left = permutate_bytes(key, PC1_L, 64, 28)
right = permutate_bytes(key, PC1_R, 64, 28)
return (left << 28) | right
def pc2(key: Bytes) -> Bytes:
"""密钥置换PC2,输入56位,输出48位"""
return permutate_bytes(key, PC2_TABLE, 56, 48)
def rotate(a: Bytes, n: int) -> Bytes:
"""循环左移28位(a是28位值)"""
for _ in range(n):
a = ((a << 1) | ((a >> 27) & 1)) & ((1 << 28) - 1)
return a
def keygen(key: Bytes, keys: list) -> None:
"""生成16个48位子密钥"""
key = pc1(key)
l = key >> 28
r = key & ((1 << 28) - 1) # 低28位
offsets = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
for i in range(16):
l = rotate(l, offsets[i])
r = rotate(r, offsets[i])
combined = (l << 28) | r
keys[i] = pc2(combined)
def s_box(a: Bytes) -> Bytes:
"""S盒替换,输入48位,输出32位"""
res = 0
for i in range(8):
# 取出第i组6位(从高位开始)
b = (a >> ((7 - i) * 6)) & ((1 << 6) - 1)
# 重排位(0,5,1,2,3,4)
b = permutate_byte(b, S_P, 6, 6)
res = (res << 4) | S_BOX[i][b]
return res
def p(a: Bytes) -> Bytes:
"""P置换,输入32位,输出32位"""
return permutate_bytes(a, P_TABLE, 32, 32)
def expand(a: Bytes) -> Bytes:
"""扩展置换,输入32位,输出48位"""
return permutate_bytes(a, E_TABLE, 32, 48)
def round_func(a: Bytes, subkey: Bytes) -> Bytes:
"""一轮Feistel函数"""
t = expand(a) ^ subkey
t = s_box(t)
t = p(t)
return t
def feistel(a: Bytes, subkey: Bytes) -> Bytes:
"""一轮Feistel网络"""
l = a >> 32
r = a & ((1 << 32) - 1)
return (r << 32) | (l ^ round_func(r, subkey))
def des(m: Bytes, key: Bytes, decrypt: bool, rounds: int) -> Bytes:
"""
DES加密/解密
m: 64位明文/密文
key: 64位原始密钥
decrypt: False加密,True解密
rounds: 执行的轮数(最多16)
"""
# 生成16个子密钥
keys = [0] * 16
keygen(key, keys)
if decrypt:
# 解密时逆序使用子密钥
for i in range(8):
keys[i], keys[15 - i] = keys[15 - i], keys[i]
# 初始置换
c = ip(m)
# 执行rounds轮
for i in range(rounds):
c = feistel(c, keys[i])
# 交换左右并逆置换
l = c >> 32
r = c & ((1 << 32) - 1)
return fp((r << 32) | l)
def encrypt(m: Bytes, rounds: int) -> Bytes:
"""使用固定密钥0xcafababedeadbeaf进行加密测试"""
return des(m, 0xcafababedeadbeaf, False, rounds)
# ---------- 测试函数 ----------
def test():
print("Test rotate: ", end='')
if rotate(167772165, 2) == 134217750:
print("OK.")
else:
print("GG!")
print("Test IP: ", end='')
if ip(81985529216486895) == 14699974583363760298:
print("OK.")
else:
print("GG!")
print("Test PC1: ", end='')
if pc1(1383827165325090801) == 67779029043144591:
print("OK.")
else:
print("GG!")
print("Test keygen: ", end='')
keys = [0] * 16
keygen(1383827165325090801, keys)
if keys[15] == 223465186400245:
print("OK.")
else:
print("GG!")
print("Test S box: ", end='')
if s_box(178261171038007) == 3725222752:
print("OK.")
else:
print("GG!")
print("Test round: ", end='')
if round_func(3707429454, 141493528337059) == 3207079049:
print("OK.")
else:
print("GG!")
def main():
test()
m = 0x0123456789ABCDEF
k = 0x133457799BBCDFF1
# 生成轮密钥
round_keys = [0] * 16
keygen(k, round_keys)
# 逐步加密并输出中间结果
d = m
print(f"Round 0 - Input: {d:016x}")
for i in range(16):
d = des(d, round_keys[i], False, i + 1)
print(f"Round {i+1:2d} - Output: {d:016x}, Round Key: {round_keys[i]:016x}")
# 完整加密
c = des(m, k, False, 16)
print(f"使用密钥进行16轮行移位得到的结果为:{c:016x}")
# 解密验证
dec = des(c, k, True, 16)
print(f"原始的输入值为: {dec:016x}")
if __name__ == "__main__":
main()

参考文章:Data Encryption Standard (DES) | Set 1 - GeeksforGeeks
代码图片生成器推荐,浏览器搜索Carbon。

上一篇:Keil MDK(uVision5)完全指导手册(个人总结,篇幅
下一篇:没有了