文章目录

  • 第一部分 DES概述
    • 1.1 DES数据加密标准简介
    • 1.2 DES算法流程
  • 第二部分 DES的C++实现
  • 第三部分 代码演示
    • 3.1 待加密的明文文件demo.txt:
    • 3.2 加密解密程序演示
    • 3.3结果展示

第一部分 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] = S2[row[1]][col[1]];res[2] = S3[row[2]][col[2]];res[3] = S4[row[3]][col[3]];res[4] = S5[row[4]][col[4]];res[5] = S6[row[5]][col[5]];res[6] = S7[row[6]][col[6]];res[7] = S8[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);   //初始置换IPDES.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 << " ";elsewriteFile << 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加密解密算法相关推荐

  1. java 实现 DES加密 解密算法

    DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥:Data也为8个字节64位,是要被加密或被解密的数据:Mode为DES的工作方式,有两种: ...

  2. DES加密解密算法Java实现

    DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小.这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半.使用子密钥对其中一半应 ...

  3. DES加密解密算法(前端后端)

    DES加密解密算法(前端&后端) 原作者 阿弥陀佛1114  原文链接:https://blog.csdn.net/zong1114/article/details/51754470 DES对 ...

  4. C# DES加密解密算法

    C# DES加密解密算法 #region DES Class /// <summary> /// ClassName: DES 加密类 /// DES加密.解密类库,字符串加密结果使用BA ...

  5. Java简单实现DES加密解密算法

    Java简单实现DES加密解密算法 文章目录 Java简单实现DES加密解密算法 DES算法介绍 实现相关java类 代码实现 DES算法介绍 DEC加密算法属于对称加密,即利用指定的密钥,按照密码的 ...

  6. 在Java中使用DES加密解密算法

    import javax.crypto.*; import javax.crypto.spec.DESKeySpec; import java.security.NoSuchAlgorithmExce ...

  7. iOS开发-DES加密解密算法

    前几天后台给了一个Java代码的加解密方式,让我这边直接用.我对应着Java上解密方法找到一些适合iOS的DES加解密算法,特总结一下 1.使用DES加密: //加密 +(NSString *) en ...

  8. Java实现DES加密解密

    DES(Data Encryption Standard)是一种对称加密算法,所谓对称加密就是加密和解密都是使用同一个密钥. 加密原理: DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位, ...

  9. C++实现古典密码-凯撒密码加密解密算法

    文章目录 第一部分 Caesar密码简介 1.1 基本思想 1.2 历史沿革 第二部分 Caesar密码的C++实现 第一部分 Caesar密码简介 1.1 基本思想 在密码学中,恺撒密码(英语:Ca ...

最新文章

  1. 【干货】Facebook产品经理:高效对接and流程解读
  2. 从零开始玩转logback
  3. rabbitmq怎么停止_rabbitmq 启动与停止
  4. [css] 说说你对前端二倍图的理解?移动端使用二倍图比一倍图有什么好处?
  5. 第49课 大大大(纯小数变整数) 《小学生C++趣味编程》
  6. html lt p gt 标签的属性,科技常识:html中amp;lt;tableamp;gt;标签的各种属性介绍_table的使用...
  7. python123判断字符串结尾_Python学习教程:在字符串的开头和结尾处做文本匹配
  8. android客户端中间人攻击,Android 中间人攻击
  9. python selenium自动化框架_一文讲透!实现一个Python+Selenium的自动化测试框架如此简单!...
  10. Gazebo Ros入门
  11. 2022苹果CMS全新二开影视源码App源码完整版
  12. 微表情测试软件排行榜,微表情心理测试分析系统:以“微”见智,识情绪辨人心...
  13. 最小径集的算法_最小割集Stoer-Wagner算法 | 学步园
  14. 云队友丨华为选拔人才,最看重这5个素质,已经用了15年
  15. 关于opencv新版无法使用LSD算法的问题
  16. 如何使用Zend Expressive建立NASA照片库
  17. 顶点计划6-4小组调研报告
  18. 用python3+ PyQt5写一个NFC模块的串口小工具的一星期
  19. 山洪灾害监测预警系统
  20. html+css+js TAB切换

热门文章

  1. git--修改用户名和邮箱的方法(全局修改和局部修改)
  2. linux usb驱动——OTG数据线与普通数据线区别
  3. 大学物理第一章 质点运动学详解
  4. 一.字符 字符串 指针字符
  5. HyperMesh网格划分简要流程小试
  6. 7-3 DAG图优化 (15 分)
  7. 视频流媒体服务器如何用OBS推流录屏或直播?
  8. leetcode 1662. Check If Two String Arrays are Equivalent(python)
  9. Berkeley db 数据库
  10. 汇编语言寻址方式总结