当前位置: 首页 > news >正文

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语言的思维在发挥作用。

http://www.jsqmd.com/news/1093312/

相关文章:

  • Windows高效LaTeX环境搭建:VS Code、MiKTeX与Perl的协同配置指南
  • Claude Code再强,也有这7件事做不了
  • 高速图像采集设计原理图:6-基于TMS320C6678、FPGA XC5VSX95T的6U CPCI 8路光纤信号处理卡
  • 环境准备1. Python 环境
  • 国内大学生论文季必用的AI论文软件有哪些?
  • Java的MethodHandle动态调用点缓存与反射在性能热点上的权衡
  • 精密锰铜电阻全解析:选型避坑与实战案例
  • 如何3分钟获取阿里云盘Refresh Token:扫码授权完整教程
  • BEV感知:MMCV/MMDetection 系列框架的注册器(Registry)插件化设计
  • ROS2 Jazzy Python 动作通信(Action)完整实操教程(斐波那契案例,可中途取消+实时反馈)
  • Windows环境下Skywalking 9与Spring Boot的实战集成:从JavaAgent到Logback日志链路追踪
  • 什么是AI Agent?
  • 推荐看看=Obsidian
  • Java 基础 (Java 入门笔记) _
  • 企业实战视角:为什么GEO优化需要“搜极星+InsGEO”的双轨并行?
  • 【计算机毕业设计案例】交互式网络博文分享交流平台基于 SpringBoot 实现 知识分享型在线博客管理系统设计与开发(程序+文档+讲解+定制)
  • 终极Windows窗口大小调整指南:3分钟掌握WindowResizer强制调整技巧
  • HTML 早已不是标签了,它现在是系统级接口:这 9 个 API 直接干翻常用
  • OpenMontage:基于开源AI模型的全链路自动化视频生成框架实战
  • GPT-5.6 正在灰度,有人在 Codex 里提前用上了,附检测方法
  • 【信号处理】为什么功率谱不是幅度谱的平方
  • 2026年批量采购无人机专用胶粘产品怎么选?行业选型指南
  • 每天5分钟玩转 Kubernetes
  • Web基础解析
  • 终极鼠标性能测试指南:用MouseTester发现你的设备真实实力
  • 深入解析PCM178x系列DAC:Delta-Sigma架构原理与音频硬件设计实战
  • 2026年6月28日博客精选
  • Java计算机毕设之基于 SpringBoot+Vue 的社区老龄关爱服务管理系统 公益助老项目发布与预约服务平台设计实现(完整前后端代码+说明文档+LW,调试定制等)
  • 奇数分频电路设计进阶:Verilog实现50%占空比的通用方法
  • 【深度学习】OpenCV 视频分析实战:背景建模 + 形态学处理实现运动目标检测