原理

加密

置换:

IP逆置换:

迭代:

PC-1置换:

PC-2置换:

子秘钥的生成:

加密函数f:

解密

代码

// C语言实现
#include<stdio.h>
#include<string.h>
/*
参考链接:https://blog.csdn.net/zidane_2014/article/details/37988657
*/
int IP_Table[64] = { //IP置换矩阵
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
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 };
int E_Table[48] = { //扩展矩阵
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 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, 1 };
int P_Table[32] = { // P 盒
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 };
int IPR_Table[64] = { //逆IP置换矩阵
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 };
int PC1_Table[56] = { //密钥第一次置换矩阵
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,
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 PC2_Table[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 };
int S_Box[8][4][16] = { //8个S盒 三维数组
// 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
};
static void CharToBit(const char input[], int output[], int bits)//把CHAR转换为INT
{
int i, j;
for (j = 0; j < 8; j++)
{
for (i = 0; i < 8; i++)
{
output[7 * (j + 1) - i + j] = (input[j] >> i) & 1;
}
}
};
static void BitToChar(const int intput[], char output[], int bits)//把INT转换为CHAR
{
int i, j;
for (j = 0; j < 8; j++)
{
for (i = 0; i < 8; i++)
{
output[j] = output[j] * 2 + intput[i + 8 * j];
}
}
};
static void Xor(int* INA, int* INB, int len)//异或操作
{
int i;
for (i = 0; i < len; i++)
{
*(INA + i) = *(INA + i) ^ *(INB + i);
}
};
static void IP(const int input[64], int output[64], int table[64])//初始IP置换
{
int i;
for (i = 0; i < 64; i++)
{
output[i] = input[table[i] - 1];//减1操作不可少!!
}
};
static void E(const int input[32], int output[48], int table[48])//E扩展
{
int i;
for (i = 0; i < 48; i++)
{
output[i] = input[table[i] - 1];
}
};
static void P(const int input[32], int output[32], int table[32])//P置换
{
int i;
for (i = 0; i < 32; i++)
{
output[i] = input[table[i] - 1];
}
};
static void IP_In(const int input[64], int output[64], int table[64])//逆IP
{
int i;
for (i = 0; i < 64; i++)
{
output[i] = input[table[i] - 1];
}
};
static void PC_1(const int input[64], int output[56], int table[56])//PC_1
{
int i;
for (i = 0; i < 56; i++)
{
output[i] = input[table[i] - 1];
}
};
static void PC_2(const int input[56], int output[48], int table[48])//PC_2
{
int i;
for (i = 0; i < 48; i++)
{
output[i] = input[table[i] - 1];
}
};
static void S(const int input[48], int output[32], int table[8][4][16])//S盒压缩
{
int i = 0;
int j = 0;
int INT[8];
for (; i < 48; i = i + 6)
{
INT[j] = table[j][(input[i] << 1) + (input[i + 5])][(input[i + 1] << 3) + (input[i + 2] << 2) + (input[i + 3] << 1) + (input[i + 4])];
j++;
}
for (j = 0; j < 8; j++)
{
for (i = 0; i < 4; i++)
{
output[3 * (j + 1) - i + j] = (INT[j] >> i) & 1;
}
}
};
static void F_func(int input[32], int output[32], int subkey[48])//完成DES算法轮变换
{
int len = 48;
int temp[48] = { 0 };
int temp_1[32] = { 0 };
E(input, temp, E_Table);
Xor(temp, subkey, len);
S(temp, temp_1, S_Box);
P(temp_1, output, P_Table);
};
static void RotateL(const int input[28], int output[28], int leftCount)//完成子密钥扩展的循环左移
{
int i;
int len = 28;
for (i = 0; i < len; i++)
{
output[i] = input[(i + leftCount) % len];
}
};
static void subKey_fun(const int input[64], int Subkey[16][48])//完成16轮子密钥生成
{
int loop = 1, loop_2 = 2;
int i, j;
int c[28], d[28];
int pc_1[56] = { 0 };
int pc_2[16][56] = { 0 };
int rotatel_c[16][28] = { 0 };
int rotatel_d[16][28] = { 0 };
PC_1(input, pc_1, PC1_Table);
for (i = 0; i < 28; i++)
{
c[i] = pc_1[i];
d[i] = pc_1[i + 28];
}
int leftCount = 0;
for (i = 1; i < 17; i++)
{
if (i == 1 || i == 2 || i == 9 || i == 16)
{
leftCount += loop;
RotateL(c, rotatel_c[i - 1], leftCount);
RotateL(d, rotatel_d[i - 1], leftCount);
}
else
{
leftCount += loop_2;
RotateL(c, rotatel_c[i - 1], leftCount);
RotateL(d, rotatel_d[i - 1], leftCount);
}
}
for (i = 0; i < 16; i++)
{
for (j = 0; j < 28; j++)
{
pc_2[i][j] = rotatel_c[i][j];
pc_2[i][j + 28] = rotatel_d[i][j];
}
}
for (i = 0; i < 16; i++)
{
PC_2(pc_2[i], Subkey[i], PC2_Table);
}
};
//DES加密运算
static void DES_Efun(char input[8], char key_in[8], int output[64])
{
int Ip[64] = { 0 };//存储初始置换后的矩阵
int output_1[64] = { 0 };
int subkeys[16][48];
int chartobit[64] = { 0 };
int key[64];
int l[17][32], r[17][32];
CharToBit(input, chartobit, 8);//正确,转换为64个二进制数的操作正确!
IP(chartobit, Ip, IP_Table);//正确,IP初始置换!
CharToBit(key_in, key, 8);//正确!
subKey_fun(key, subkeys);//正确!
for (int i = 0; i < 32; i++)
{
l[0][i] = Ip[i];
r[0][i] = Ip[32 + i];
}
for (int j = 1; j < 16; j++)//前15轮的操作
{
for (int k = 0; k < 32; k++)
{
l[j][k] = r[j - 1][k];
}
F_func(r[j - 1], r[j], subkeys[j - 1]);
Xor(r[j], l[j - 1], 32);
}
int t = 0;
for (t = 0; t < 32; t++)//最后一轮的操作
{
r[16][t] = r[15][t];
}
F_func(r[15], l[16], subkeys[15]);
Xor(l[16], l[15], 32);
for (t = 0; t < 32; t++)
{
output_1[t] = l[16][t];
output_1[32 + t] = r[16][t];
}
IP_In(output_1, output, IPR_Table);
};
//完成DES解密运算
static void DES_Dfun(int input[64], char key_in[8], char output[8])
{
int Ip[64] = { 0 };//存储初始置换后的矩阵
int output_1[64] = { 0 };
int output_2[64] = { 0 };
int subkeys[16][48];
int chartobit[64] = { 0 };
int key[64];
int l[17][32], r[17][32];
IP(input, Ip, IP_Table);//正确,IP初始置换!
CharToBit(key_in, key, 8);//正确!
subKey_fun(key, subkeys);//正确!
for (int i = 0; i < 32; i++)
{
l[0][i] = Ip[i];
r[0][i] = Ip[32 + i];
}
for (int j = 1; j < 16; j++)//前15轮的操作
{
for (int k = 0; k < 32; k++)
{
l[j][k] = r[j - 1][k];
}
F_func(r[j - 1], r[j], subkeys[16 - j]);
Xor(r[j], l[j - 1], 32);
}
int t = 0;
for (t = 0; t < 32; t++)//最后一轮的操作
{
r[16][t] = r[15][t];
}
F_func(r[15], l[16], subkeys[0]);
Xor(l[16], l[15], 32);
for (t = 0; t < 32; t++)
{
output_1[t] = l[16][t];
output_1[32 + t] = r[16][t];
}
IP_In(output_1, output_2, IPR_Table);
BitToChar(output_2, output, 8);
}; int main()
{
int output[64] = { 0 };
char MIN[9] = { 0 }; // 明文
char MI[9] = { 0 }; //秘钥
printf("请输入明文(8个字符):");
gets(MIN);
printf("请输入秘钥(8个字符):");
gets(MI);
DES_Efun(MIN, MI, output);
printf("密文如下:\n");
for (int i = 0; i < 64; i++)
{
printf("%d", output[i]);
if ((i + 1) % 4 == 0)
printf("\n");
}
printf("\n");
printf("解密功能\n");
DES_Dfun(output, MI, MIN);
printf("明文如下:\n");
for (int i = 0; i < 8; i++)
{
printf("%c", MIN[i]);
}
printf("\n");
system("pause");
return 0;
}

DES 实现的更多相关文章

  1. 在.NET Core 里使用 BouncyCastle 的DES加密算法

    .NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用 ...

  2. 使用 JavaScriptService 在.NET Core 里实现DES加密算法

    文章<ASP.NET Core love JavaScript>和<跨平台的 NodeJS 组件解决 .NetCore 不支持 System.Drawing图形功能的若干问题> ...

  3. [C#] 简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)

    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Wen. ...

  4. 4、DES和RSA简介

    DES是分组加密算法,速度快,使用单一密钥,加密解密都使用同一个密钥,一般用于大量数据加密,目前处于半淘汰状态. RSA算法是流式加密算法,速度慢,但是使用成对的密钥,加密解密使用不同的密钥,有利于保 ...

  5. Android数据加密之Des加密

    前言: 端午节前有个同事咨询我有关Android DES加密的相关实现,简单的实现了一下,今天来总结一下. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes加密 ...

  6. 密码学应用(DES,AES, MD5, SHA1, RSA, Salt, Pkcs8)

    目录 一.数据加密标准 - Data Encryption Standard(DES) 二.高级加密标准 - Advanced Encryption Standard(AES) 三.消息摘要算法第五版 ...

  7. When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)

    关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...

  8. Java 加解密 AES DES TripleDes

    package xxx.common.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypt ...

  9. .NET和JAVA中BYTE的区别以及JAVA中“DES/CBC/PKCS5PADDING” 加密解密在.NET中的实现

    场景:java 作为客户端调用已有的一个.net写的server的webservice,输入string,返回字节数组. 问题:返回的值不是自己想要的,跟.net客户端直接调用总是有差距 分析:平台不 ...

  10. php使用openssl进行Rsa长数据加密(117)解密(128) 和 DES 加密解密

    PHP使用openssl进行Rsa加密,如果要加密的明文太长则会出错,解决方法:加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文:解密的时候需要128个字符解密一下,然后拼接成数据. 加 ...

随机推荐

  1. CentOS7设置内网时间同步

    1.yum 安装 NTP服务器 [root@master ~]# yum -y install ntp 2.启动ntpd服务 [root@master ~]# systemctl start ntpd ...

  2. 简说Modbus-RTU与Modbus-ASCII

    Modbus在串行总线通信中的协议有RTU和ASCII两种.RTU是Remote Terminal Unit的缩写,意思是远程终端单元.ASCII是American Standard Code for ...

  3. 多测师讲解html _图片标签003_高级讲师肖sir

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>段 ...

  4. 多测师讲解pythonl _字符,列表,元组,字典,集合,归纳_高级讲师肖sir

  5. MeteoInfoLab脚本示例:水汽通量散度计算

    用ncep数据计算水汽通量散度的脚本.需要air, uwnd, vwnd和rhum变量.数据是4维数据,需要固定时间维和高度维,数据中纬度维的数据是反向的,因此读取时需要特殊的设置(::-1).脚本中 ...

  6. 用Pycharm创建指定的Django版本

    最近在学习胡阳老师(the5fire)的<Django企业级开发实战>,想要使用pycharm创建django项目时,在使用virtualenv创建虚拟环境后,在pycharm内,无论如何 ...

  7. day50 Pyhton 前端01

    文档结构: <!-- 定义文档类型 --> <!DOCTYPE html> <!-- 文档 --> <html lang='en'> <!-- 仅 ...

  8. day03 Pyhton学习

    昨日回顾 1.while循环 语法 while 条件: 语句 else: 语句 执行语句:判断语句是否为真.如果真,执行循环,然后再次判断条件,如果不满足执行else语句. break 结束循环 co ...

  9. centos7搭建docker环境

    Docker简介 Docker是一种虚拟化技术,用来将你的应用程序及其依赖的环境一起打包成一个镜像发布,使得在任何地方都能获得相同的运行环境. Docker 是一个开源项目,诞生于 2013 年初,最 ...

  10. linux(centos8):jmeter5.3并发测试实例(参数在范围内随机取值)

    一,测试的url地址说明: 1,这是一个秒杀功能的url: http://127.0.0.1:8080/second/skusecond?actid=2020&skuid=cpugreen&a ...