You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
8.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
// 初始置换表
const int TRANS_INIT[] = {
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 };
// 结尾置换表
const int TRANS_END[] = {
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 };
// 密钥置换表将64位密钥变成56位
const int TRANS_64to56[] = {
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 };
// 压缩置换将56位密钥压缩成48位子密钥
const int TRANS_56to48[] = {
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 };
// 循环左移表
const int SHIFT_TAB[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
// 扩展置换表将32位扩展至48位
const int EXPAND_32to48[] = { 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 };
// S盒每个S盒是4x16的置换表6位->4位
const int S_BOX[8][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}
},
{
{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}
}
};
// 32位置换32位 -> 32位
const int TRANS_32to32[] = {
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 };
//输出数组内容
template <typename T>
void printarr(T* line,int len)
{
for (int i = 0; i < len; i++)
{
cout << line[i];
}
cout << endl;
}
//将密钥转化为64位二进制
void SETKEY(const char Key_C[8], bool Key_B[64]) {
for (int i = 0; i < 8; i++) {
char c = Key_C[i];
for (int j = 0; j < 8; j++) {
Key_B[i * 8 + j] = (c >> (7 - j)) & 1;
}
}
}
//字节转化为bit
void ByteToBit(bool* Outs, const char* In, int bits) {
for (int i = 0; i < bits; i++) {
char c = In[i];
for (int j = 0; j < 8; j++) {
Outs[i * 8 + j] = (c >> (7 - j)) & 1;
}
}
}
//bit转换为字节
void BitToByte(char* Outs, const bool* In, int bits) {
for (int i = 0; i < bits; i++) {
char c = 0;
for (int j = 0; j < 8; j++) {
c |= (In[i * 8 + j] << (7 - j));
}
Outs[i] = (char)c;
}
}
//循环左移的实现
void CYCLELEFT(bool* In, int len, int loop) {
bool* temp=new bool [len];
for (int i = 0; i < len; i++) {
temp[i] = In[(i + loop) % len];
}
//memcpy拷贝函数
memcpy(In, temp, len * sizeof(bool));
delete [] temp;
}
//生成每一轮的子密钥
void Set_SubKey(bool subKey[16][48], bool Key[64]) {
bool K_plus[56];
//选择置换
for (int i = 0; i < 56; i++) {
K_plus[i] = Key[TRANS_64to56[i] - 1];
}
bool C[28], D[28];
memcpy(C, K_plus, 28);
memcpy(D, K_plus + 28, 28);
for (int i = 0; i < 16; i++) {
CYCLELEFT(C, 28, SHIFT_TAB[i]);
CYCLELEFT(D, 28, SHIFT_TAB[i]);
bool CD[56];
memcpy(CD, C, 28);
memcpy(CD + 28, D, 28);
for (int j = 0; j < 48; j++) {
subKey[i][j] = CD[TRANS_56to48[j] - 1];
}
}
}
//实现左半部分与轮函数结果的异或操作
void XOR(bool* InA, const bool* InB, int len) {
for (int i = 0; i < len; i++) {
InA[i] ^= InB[i];
}
}
//选择变换压缩S盒替代
void S_BOXF(bool Out[32], const bool In[48]) {
for (int i = 0; i < 8; i++) {
int row = (bool)(In[i * 6] << 1) | In[i * 6 + 5];
int col = (bool)(In[i * 6 + 1] << 3) | (In[i * 6 + 2] << 2) | (In[i * 6 + 3] << 1) | In[i * 6 + 4];
int val = S_BOX[i][row][col];
Out[i * 4] = (val >> 3) & 1;
Out[i * 4 + 1] = (val >> 2) & 1;
Out[i * 4 + 2] = (val >> 1) & 1;
Out[i * 4 + 3] = val & 1;
}
}
//轮函数F变换
void F_FUNCTION(bool In[32], const bool Ki[48]) {
bool expanded[48];
for (int i = 0; i < 48; i++) {
expanded[i] = In[EXPAND_32to48[i] - 1];
}
XOR(expanded, Ki, 48);
bool s_out[32];
S_BOXF(s_out, expanded);
bool p_out[32];
for (int i = 0; i < 32; i++) {
p_out[i] = s_out[TRANS_32to32[i] - 1];
}
memcpy(In, p_out, 32);
}
//DES操作type为1即加密为0即解密
void DES(char Out[8], char In[8], const bool subKey[16][48], bool Type) {
bool data[64];
ByteToBit(data, In, 8);
bool ip_data[64];
for (int i = 0; i < 64; i++) {
ip_data[i] = data[TRANS_INIT[i] - 1];
}
bool L[32], R[32];
memcpy(L, ip_data, 32);
memcpy(R, ip_data + 32, 32);
for (int round = 0; round < 16; round++) {
bool tempR[32];
memcpy(tempR, R, 32);
F_FUNCTION(tempR, subKey[Type ? round : 15 - round]);
XOR(tempR, L, 32);
memcpy(L, R, 32);
memcpy(R, tempR, 32);
}
bool RL[64];
memcpy(RL, R, 32);
memcpy(RL + 32, L, 32);
bool result[64];
for (int i = 0; i < 64; i++) {
result[i] = RL[TRANS_END[i] - 1];
}
BitToByte(Out, result, 8);
}
int main()
{
char text[8], destext[8], newline[8],key[8];
bool skey[64],stext[64],subkey[16][48],answer[64];
cout << "请输入明文:";
for (int i = 0; i < 8; i++)
{
cin >> text[i];
}
cout << "请输入密钥:";
for (int i = 0; i < 8; i++)
{
cin >> key[i];
}
cout << "明文:";
printarr(text, 8);
cout << "密钥:";
printarr(key, 8);
cout << "明文二进制码:";
ByteToBit(stext,text,8);
printarr(stext, 64);
SETKEY(key, skey);
cout << "密钥二进制码:";
printarr(skey, 64);
Set_SubKey(subkey, skey);
DES(destext, text, subkey, 1);
ByteToBit(answer, destext, 8);
cout << "密文为:";
printarr(answer, 64);
cout << "测试对刚加密的密文进行解密操作";
DES(newline, destext, subkey, 0);
cout << "解密结果为";
printarr(newline, 8);
}