C++实现DES加密解密算法
程序员文章站
2022-05-15 14:59:38
...
文章目录
第一部分 DES概述
1.1 DES数据加密标准简介
DES全称为Data Encryption Standard,即数据加密标准,是一种使用**加密的块算法,1977年被美国联邦*的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级*通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。DES设计中使用了分组密码设计的两个原则:混淆(confusion)和扩散(diffusion),其目的是抗击敌手对密码系统的统计分析。混淆是使密文的统计特性与**的取值之间的关系尽可能复杂化,以使**和明文以及密文之间的依赖性对密码分析者来说是无法利用的。扩散的作用就是将每一位明文的影响尽可能迅速地作用到较多的输出密文位中,以便在大量的密文中消除明文的统计结构,并且使每一位**的影响尽可能迅速地扩展到较多的密文位中,以防对**进行逐段破译。
转载自:百度百科
1.2 DES算法流程
第二部分 DES的C++实现
我在代码里附上了详细的注释,使用面向对象编程风格,提高了代码的可读性与层次性,希望本代码能够对你有所帮助。
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
class myDES {
private:
vector<int>initPermute //初始置换表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 };
vector<int>inv_initPermute //逆初始置换表Inverse 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 };
vector<int>E //选择扩展运算E表
{ 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 };
vector<int>P //置换运算表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 };
vector<int>PC1 //置换选择表1(64bits->56bits)
{ 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 };
vector<int>PC2 //置换选择表2(56bits->48bits)
{ 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 };
vector<int>leftShift{ 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 }; //循环左移位数表
vector<vector<int>>S1 //S盒换位表
{
{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}
};
vector<vector<int>>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}
};
vector<vector<int>>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}
};
vector<vector<int>>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}
};
vector<vector<int>>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}
};
vector<vector<int>>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}
};
vector<vector<int>>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}
};
vector<vector<int>>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}
};
public:
vector<int>generateKey(vector<char>inputkey) { //将输入进来的8个字符**转换为64位二进制
vector<int>myKey(64);
int i, j, m;
for (i = 0; i < 8; i++) {
vector<int>temp{ 0,0,0,0,0,0,0,0 };
m = (int)inputkey[i];
for (j = 0; m != 0; j++) {
temp[j] = m % 2;
m /= 2;
}
for (j = 0; j < 8; j++) {
myKey[(i * 8) + j] = temp[7 - j];
}
}
return myKey;
}
vector<int>generateKey_PC1(vector<int>key_64bits) { //将64位的**通过PC1表置换生成56位
vector<int>myKey(56);
int index;
for (index = 0; index < 56; index++) {
myKey[index] = key_64bits[PC1[index] - 1];
}
return myKey;
}
void divideKey(vector<int>srcKey, vector<int>&leftkey, vector<int>&rightkey) { //将56位的**分成左右两部分,每部分28位
int i;
for (i = 0; i < 28; i++) {
leftkey[i] = srcKey[i];
rightkey[i] = srcKey[i + 28];
}
return;
}
void shiftKey(int round, vector<int>&leftkey, vector<int>&rightkey) { //按照round对应的移位数,分别对左右**循环左移操作
int bits_of_shift = leftShift[round];
int i, temp1, temp2;
if (bits_of_shift == 1) { //循环左移一位的情况
temp1 = leftkey[0];
for (i = 0; i < 27; i++) {
leftkey[i] = leftkey[i + 1];
}
leftkey[27] = temp1;
temp1 = rightkey[0];
for (i = 0; i < 27; i++) {
rightkey[i] = rightkey[i + 1];
}
rightkey[27] = temp1;
}
else { //循环左移两位的情况
temp1 = leftkey[0];
temp2 = leftkey[1];
for (i = 0; i < 26; i++) {
leftkey[i] = leftkey[i + 2];
}
leftkey[26] = temp1;
leftkey[27] = temp2;
temp1 = rightkey[0];
temp2 = rightkey[1];
for (i = 0; i < 26; i++) {
rightkey[i] = rightkey[i + 2];
}
rightkey[26] = temp1;
rightkey[27] = temp2;
}
return;
}
vector<int>combineKey(vector<int>leftkey, vector<int>rightkey) { //**合并,将每次移位后的28位**合并成一个56位**
vector<int>myKey(56);
int i;
for (i = 0; i < 28; i++) {
myKey[i] = leftkey[i];
myKey[i + 28] = rightkey[i];
}
return myKey;
}
vector<int>generateKey_PC2(vector<int>key_56bits) { //将合并好的56位**进行PC2表的变换生成每一轮的48位子**
vector<int>myKey(48);
int index;
for (index = 0; index < 48; index++) {
myKey[index] = key_56bits[PC2[index] - 1];
}
return myKey;
}
vector<int>convert_text_64bits(vector<char>text) { //将明文转换成64位二进制存储
vector<int>myText(64);
int i, j, m;
for (i = 0; i < 8; i++) {
vector<int>temp{ 0,0,0,0,0,0,0,0 };
m = (int)text[i];
for (j = 0; m != 0; j++) {
temp[j] = m % 2;
m /= 2;
}
for (j = 0; j < 8; j++) {
myText[(i * 8) + j] = temp[7 - j];
}
}
return myText;
}
vector<int>permute_IP(vector<int>text) { //使用Init_permute置换表(IP)进行初始置换
vector<int>myText(64);
int index;
for (index = 0; index < 64; index++) {
myText[index] = text[initPermute[index] - 1];
}
return myText;
}
void divideText(vector<int>srcText, vector<int>& leftText, vector<int>& rightText) { //将初始置换后的64位比特分成两组32位比特
int index;
for (index = 0; index < 32; index++) {
leftText[index] = srcText[index];
rightText[index] = srcText[index + 32];
}
return;
}
vector<int>expandText(vector<int>text) { //对每轮迭代的有半部分32比特经过E表扩展成48比特
vector<int>myText(48);
int index;
for (index = 0; index < 48; index++) {
myText[index] = text[E[index] - 1];
}
return myText;
}
vector<int>text_XOR_key(vector<int>text, vector<int>key) { //每一轮扩展后的48比特明文与轮**进行异或
vector<int>res(48);
int i;
for (i = 0; i < 48; i++) {
res[i] = text[i] ^ key[i];
}
return res;
}
vector<int>S_transfer(vector<int>text) { //将48位比特经过S变换生成8个十进制数
vector<int>res(8);
vector<int>row(8), col(8);
for (int i = 0; i < 8; i++) {
row[i] = text[i * 6 + 0] * 2 + text[i * 6 + 5]; //每个6比特输入第一个和第六个比特组成一个二进制数选择S盒中的代换行
col[i] = text[i * 6 + 1] * 8 + text[i * 6 + 2] * 4 + text[i * 6 + 3] * 2 + text[i * 6 + 4] * 1; //中间4个比特选择S盒的代换列
}
res[0] = S1[row[0]][col[0]];
res[1] = S1[row[1]][col[1]];
res[2] = S1[row[2]][col[2]];
res[3] = S1[row[3]][col[3]];
res[4] = S1[row[4]][col[4]];
res[5] = S1[row[5]][col[5]];
res[6] = S1[row[6]][col[6]];
res[7] = S1[row[7]][col[7]];
return res;
}
vector<int>S_transfer_32bits(vector<int>text) { //将8位十进制数转换为32位二进制数存储
vector<int>res(32);
vector<int>arr(4, 0);
for (int i = 0; i < 8; i++) {
int c;
c = (int)text[i];
for (int k = 3; c != 0; k--) {
arr[k] = c % 2;
c /= 2;
}
for (int p = 0; p < 4; p++) {
res[i * 4 + p] = arr[p];
}
}
return res;
}
vector<int>P_transfer_32bits(vector<int>text) { //将经过S盒代换后的32位结果再进行P表置换
vector<int>myText(32);
int i;
for (i = 0; i < 32; i++) {
myText[i] = text[P[i] - 1];
}
return myText;
}
vector<int>L_XOR_R(vector<int>L, vector<int>R) { //将左32比特与轮函数处理后的右32比特进行异或操作
vector<int>myText(32);
int i;
for (i = 0; i < 32; i++) {
myText[i] = L[i] ^ R[i];
}
return myText;
}
void L_EXCHANGE_R(vector<int>& L0, vector<int>& R0, vector<int>& Ri) { //每一轮结束时左右部分32位进行互换
for (int i = 0; i < 32; i++) {
L0[i] = R0[i];
R0[i] = Ri[i];
}
return;
}
void lastExchange(vector<int>& Li, vector<int>& R0, vector<int>& L0) { //最后一步左右交换步骤
int i;
for (i = 0; i < 32; i++) {
Li[i] = R0[i];
}
for (int i = 0; i < 32; i++) {
R0[i] = L0[i];
}
for (int i = 0; i < 32; i++) {
L0[i] = Li[i];
}
return;
}
vector<int>L_COMBINE_R(vector<int>left, vector<int>right) { //最后将左右32位比特合并成64位比特密文
vector<int>ans(64);
int i;
for (i = 0; i < 32; i++) {
ans[i] = left[i];
}
for (i = 32; i < 64; i++) {
ans[i] = right[i - 32];
}
return ans;
}
vector<int>permute_InvIP(vector<int>myText) { //初始置换的逆置换
vector<int>ans(64);
int index;
for (index = 0; index < 64; index++) {
ans[index] = myText[inv_initPermute[index] - 1];
}
return ans;
}
vector<char>bin_to_hex(vector<vector<int>>binaryStream) { //将二进制密文转换为十六进制密文存储
vector<char>hexFile;
vector<char>letterHash{ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
char c;
int i, j, v;
for (i = 0; i < binaryStream.size(); i++) {
for (j = 0; j < binaryStream[i].size() / 4; j++) {
v = binaryStream[i][j * 4 + 0] * 8 + binaryStream[i][j * 4 + 1] * 4 + binaryStream[i][j * 4 + 2] * 2 + binaryStream[i][j * 4 + 3] * 1;
c = letterHash[v];
hexFile.push_back(c);
}
}
return hexFile;
}
vector<vector<int>>hex_to_bin(vector<char>hexStream) { //将十六进制密文转位二进制ASCII码二维数组,每64比特为一组
vector<vector<int>>binFile;
vector<int>group_64bits;
map<char, vector<int>>hexHash;
hexHash['0'] = { 0,0,0,0 };
hexHash['1'] = { 0,0,0,1 };
hexHash['2'] = { 0,0,1,0 };
hexHash['3'] = { 0,0,1,1 };
hexHash['4'] = { 0,1,0,0 };
hexHash['5'] = { 0,1,0,1 };
hexHash['6'] = { 0,1,1,0 };
hexHash['7'] = { 0,1,1,1 };
hexHash['8'] = { 1,0,0,0 };
hexHash['9'] = { 1,0,0,1 };
hexHash['A'] = { 1,0,1,0 };
hexHash['B'] = { 1,0,1,1 };
hexHash['C'] = { 1,1,0,0 };
hexHash['D'] = { 1,1,0,1 };
hexHash['E'] = { 1,1,1,0 };
hexHash['F'] = { 1,1,1,1 };
int i, j, k;
for (i = 0; i < hexStream.size() / 16; i++) {
for (j = 0; j < 16; j++) {
for (k = 0; k < 4; k++) {
group_64bits.push_back(hexHash[hexStream[i * 16 + j]][k]);
}
}
binFile.push_back(group_64bits);
group_64bits.clear();
}
return binFile;
}
vector<char>bin_to_dec(vector<int>binStream) { //将二进制明文转换为十进制并转成字符
vector<char>myText(8);
int i, j, v;
for (i = 0; i < 8; i++) {
v = 0;
for (j = 0; j < 8; j++) {
v += binStream[i * 8 + j] * pow(2, 7 - j);
}
myText[i] = v;
}
return myText;
}
};
int main() {
myDES DES;
vector<char>inputKey; //保存输入的8位字符型**,其中第九位是'\0'
vector<int>binaryKey(64); //将输入的二进制**保存为**的二进制形式
vector<int>key_PC1(56); //将经过置换选择PC1表生成的56位**保存在这个数组
vector<int>left_key(28); //将**生成左右两半部分,每部分28位
vector<int>right_key(28);
vector<int>combine_key(56); //将每次循环移位后的**合并成56bits**
vector<vector<int>>key(16, vector<int>(48)); //二维数组存储每次经过PC2表生成的48位子**
vector<int>exchangeText(64); //用于存储每一轮经过左右32位交换后的中间结果
vector<char>clearText; //用于存储原始明文
vector<char>cipherText; //用于存储加密密文
vector<char>groupText(8); //用于存储每8个字符的分组
vector<int>binaryGroupText(64); //用于存储分组字符的64位二进制形式
vector<int>binaryGroupText_IP(64); //用于存储初始置换后明文的二进制
vector<int>L0(32), Li(32), R0(32), Ri(32); //用于存储被分成左右各32位进行迭代的二进制文本
vector<int>R0_E(48); //用于存储每轮迭代右半部分经过E表扩展的48比特
vector<int>R_XOR_K(48); //用于存储扩展后的右半部分与每***异或后的结果
vector<int>R_S(8); //用于存放经过8个S盒查找得到的8个十进制结果
vector<int>binary_R_S(32); //用于将经过S盒代换后的结果转换成二进制存储
vector<int>R_P(32); //用于存储经过P表换位之后的二进制结果
vector<vector<int>>outText; //用于存储每一轮加密后的8位密文,每8位一组存储
vector<int>outText_64bits(64); //每次加密8个字符,每次生成64比特二进制密文
vector<int>lastText; //用于存储每一轮最后合并成64位的密文
vector<int>clearText_64bits(64); //用于存储每次解密生成的64位明文二进制
vector<vector<int>>clearText_outText; //用于存储每一轮解密后的64位明文
vector<char>clearText_decimal(8); //用于存储每次解密生成的8个明文字符
cout << "---------- Welcome to StarKirby DES crypto system ----------" << endl;
int flag = 1;
int mode;
while (flag) {
cout << "Please input the mode of function: [1->encrypt; 2->decrypt; 3->exit]" << endl;
cin >> mode;
if (mode != 1 && mode != 2 && mode != 3) { //选择DES系统加密/解密功能
cout << "Wrong input! Please check your mode!" << endl;
cin >> mode;
}
if (mode == 3) {
cout << "Thank you for using!";
return 0;
}
cout << "Please input 8-bit key: "; //输入初始的8位**
inputKey.clear();
for (int i = 0; i < 8; i++) {
char c;
cin >> c;
inputKey.push_back(c);
}
while (inputKey.size() != 8) { //对输入进行合法性检查
cout << "Wrong bits of key, please input 8-bit key: ";
inputKey.clear();
for (int i = 0; i < 8; i++) {
char c;
cin >> c;
inputKey.push_back(c);
}
}
binaryKey = DES.generateKey(inputKey); //将初始8位**转换为64位二进制**存储
key_PC1 = DES.generateKey_PC1(binaryKey); //将64位**经过PC1表变换为56位存储
DES.divideKey(key_PC1, left_key, right_key); //将56位**分成等长左右两个**,分别都是28位
for (int round = 0; round < 16; round++) { //将之后加密所需要的16***生成并存储与二维数组中
DES.shiftKey(round, left_key, right_key);//按照轮数与循环左移表分别对左右**进行循环左移
combine_key = DES.combineKey(left_key, right_key); //将循环左移后的**重新合并成56位**
key[round] = DES.generateKey_PC2(combine_key); //将得到的**经过PC2变换最终生成每一轮的48位轮**
}
if (mode == 1) { //DES加密过程
cout << "Please input the name of source file: ";
string fileName;
cin >> fileName;
ifstream readFile;
readFile.open("C:\\Users\\StarKirby\\source\\repos\\Crypto-assignment-DES\\Data\\" + fileName + ".txt");
char c;
while (!readFile.eof()) { //将文本文件读入字符向量中
readFile >> c;
if(!readFile.eof())
clearText.push_back(c);
}
readFile.close();
//clearText.push_back('\0');
if (clearText.size() == 0) {
cout << "Wrong input! Please check your source file." << endl;
return 0;
}
int surplus, group;
surplus = clearText.size() % 8; //明文最后几位长度
group = (clearText.size() - 1) / 8 + 1; //明文的组数(8位一组)
for (int p = 0; p < group; p++) {
if (p == (group - 1) && surplus != 0) { //如果有非8位的剩余,则不足8位的用空格填充
for (int i = 0; i < surplus; i++)
groupText[i] = clearText[8 * p + i];
for (int i = surplus; i < 8; i++)
groupText[i] = ' ';
}
else {
for (int i = 0; i < 8; i++) {
groupText[i] = clearText[8 * p + i];
}
}
binaryGroupText = DES.convert_text_64bits(groupText); //将每一组明文转换成64位二进制存储
binaryGroupText_IP = DES.permute_IP(binaryGroupText); //初始置换IP
DES.divideText(binaryGroupText_IP, L0, R0); //将初始置换后的64比特分成两组32比特存储
int round = 0;
for (round = 0; round < 16; round++) { //接下来进行16轮迭代加密
R0_E = DES.expandText(R0); //将每轮迭代的右半部分32比特扩展成48比特
R_XOR_K = DES.text_XOR_key(R0_E, key[round]); //每轮扩展后的48比特明文与每一轮**进行异或操作
R_S = DES.S_transfer(R_XOR_K); //对异或后的明文进行S盒变换
binary_R_S = DES.S_transfer_32bits(R_S); //对前述步骤产生的结果转换成32位比特存储
R_P = DES.P_transfer_32bits(binary_R_S); //进行轮函数最后一步P盒置换产生32位密文
Ri = DES.L_XOR_R(L0, R_P); //与前一次左部32位进行异或运算,得到本轮迭代的右部32位比特
DES.L_EXCHANGE_R(L0, R0, Ri); //每一轮结束时左右部分32位进行互换
}
DES.lastExchange(Li, R0, L0); //最后一个左右32位比特交换
lastText = DES.L_COMBINE_R(L0, R0); //将左右两部分32比特合并成64比特
outText_64bits = DES.permute_InvIP(lastText); //逆初始置换,每次生成64比特二进制数据
outText.push_back(outText_64bits); //将每次得到的64比特数据存入二进制密文数组中
}
//for (int i = 0; i < outText.size(); i++) {
// for (int j = 0; j < outText[i].size(); j++) {
// cout << outText[i][j];
// }
// cout << endl;
//}
cipherText = DES.bin_to_hex(outText); //将得到的二进制密文转换成十六进制存储
ofstream writeFile;
writeFile.open("C:\\Users\\StarKirby\\source\\repos\\Crypto-assignment-DES\\Data\\" + fileName + "_ciphertext.txt");
for (int i = 0; i < cipherText.size(); i++) {
writeFile << cipherText[i];
}
cout << "Successfully encrypt the source file to your path!" << endl;
}
else { //DES解密过程
clearText.clear();
cout << "Please input the name of ciphertext file: ";
string fileName;
cin >> fileName;
ifstream readFile;
readFile.open("C:\\Users\\StarKirby\\source\\repos\\Crypto-assignment-DES\\Data\\" + fileName + ".txt");
char c;
cipherText.clear();
while (!readFile.eof()) { //将文本文件读入字符向量中
readFile >> c;
if(!readFile.eof())
cipherText.push_back(c);
}
readFile.close();
if (cipherText.size() % 16 != 0) {
cout << "Please check your ciphertext! the length of your text must be multiple of 16!" << endl;
return 0;
}
outText.clear(); //如果之前有加密则此行代码至关重要,必须清空缓冲区存放密文数组
outText = DES.hex_to_bin(cipherText); //将十六进制密文存储为二进制矩阵,每64位为一组
//for (int i = 0; i < outText.size(); i++) {
// for (int j = 0; j < outText[i].size(); j++) {
// cout << outText[i][j];
// }
// cout << endl;
//}
for (int group = 0; group < outText.size(); group++) {
binaryGroupText.clear();
binaryGroupText = outText[group]; //将每64位密文进行存储
binaryGroupText_IP.clear();
binaryGroupText_IP = DES.permute_IP(binaryGroupText); //初始换位
DES.divideText(binaryGroupText_IP, L0, R0); //将初始换位的64比特的二进制密文分为左右两组,每组32比特
int round;
for (round = 0; round < 16; round++) { //十六轮迭代开始
R0_E.clear();
R0_E = DES.expandText(R0); //将每轮迭代的右半部分32比特扩展成48比特
R_XOR_K.clear();
R_XOR_K = DES.text_XOR_key(R0_E, key[15 - round]); //每轮扩展后的48比特明文与每一轮**进行异或操作(解***和加密顺序相反)
R_S.clear();
R_S = DES.S_transfer(R_XOR_K); //对异或后的明文进行S盒变换
binary_R_S.clear();
binary_R_S = DES.S_transfer_32bits(R_S); //对前述步骤产生的结果转换成32位比特存储
R_P.clear();
R_P = DES.P_transfer_32bits(binary_R_S); //进行轮函数最后一步P盒置换产生32位密文
Ri.clear();
Ri = DES.L_XOR_R(L0, R_P); //与前一次左部32位进行异或运算,得到本轮迭代的右部32位比特
DES.L_EXCHANGE_R(L0, R0, Ri); //每一轮结束时左右部分32位进行互换
}
DES.lastExchange(Li, R0, L0); //最后一个左右32位比特交换
lastText.clear();
lastText = DES.L_COMBINE_R(L0, R0); //将左右两部分32比特合并成64比特
clearText_64bits = DES.permute_InvIP(lastText); //逆初始置换,每次生成64比特二进制明文数据
clearText_outText.push_back(clearText_64bits); //将每次得到的64比特数据存入二进制明文数组中
}
for (int i = 0; i < clearText_outText.size(); i++) {
clearText_decimal = DES.bin_to_dec(clearText_outText[i]);
for (int c = 0; c < clearText_decimal.size(); c++) {
clearText.push_back(clearText_decimal[c]);
}
clearText_decimal.clear();
}
ofstream writeFile;
writeFile.open("C:\\Users\\StarKirby\\source\\repos\\Crypto-assignment-DES\\Data\\" + fileName + "_cleartext.txt");
for (int i = 0; i < clearText.size(); i++) {
if ((int)clearText[i]==32)
writeFile << " ";
else
writeFile << clearText[i];
}
cout << "Successfully decrypt the ciphertext to your path!" << endl;
}
cout << "Continue? [0->No 1->Yes]: ";
cin >> flag;
}
cout << "-----------Thank you for using!-----------";
return 0;
}
注:本代码在VS2019中已经调试通过。
第三部分 代码演示
3.1 待加密的明文文件demo.txt:
3.2 加密解密程序演示
3.3结果展示
本实验展示了DES对本博客链接的加密操作,并正确进行了解密。
上一篇: C# 实现DES加密解密
下一篇: DES加密解密