DES C++分组实现
#include<iostream>
#include<string>
#include"Numbertables.h"
#define N 50
using namespace std;
typedef bool BITE;
class DES_ALG {
public:
void DesEnter(string &Data_in, BITE** Data_Out,string key, int Mode, int dataLen);
int DesMac(const BITE* mac_data, BITE*mac_code,int datalen, BITE key[64]);
int Get_Nums();
int Get_GroupNUm();
private:
int NumS = 0;
int GroupNum = 0;
void XOR(BITE* Data_Out, BITE* Data_In, int Num);
void CreSubKey(string Data_in);
void Enc_DES(BITE* Mes_Out, string Mes_In);
void Dec_DES(string &Mes_Out, BITE* Mes_In);
void ASC_Bin(BITE* Data_Out, string Data_in, int Num);
void Bin_ASC(string &Mes_out, BITE* Mes_In, int Num);
void TableTrans(BITE* Date_Out, BITE* Data_In, const char* table, int Num);
void BitsCopy(BITE* Data_Out, BITE* Data_In, int Num);
void LoopMove(BITE* Data_In, int Len, int Num);
void F_change(BITE Data_In[32], BITE Data_Ki[48]);
void S_change(BITE Data_Out[32], BITE Data_In[48]);
};
int DES_ALG::Get_Nums() {
return NumS;
}
int DES_ALG::Get_GroupNUm() {
return GroupNum;
}
void PrintBin(BITE* data, int Num) {
int i = 0;
for (; i < Num; i++) {
cout << data[i];
if ((i+1) % 8 == 0) { cout << endl; }
}
cout << endl;
}
void DES_ALG::Bin_ASC(string &Mes_out, BITE* Mes_In, int Num) {
int i = 0;
for (; i < Num; i += 8) {
int temp = (Mes_In[i+7] << 7) + (Mes_In[i + 6] << 6) + (Mes_In[i + 5] << 5) + (Mes_In[i + 4] << 4) + (Mes_In[i + 3] << 3) + (Mes_In[i + 2] << 2) + (Mes_In[i + 1] << 1) + Mes_In[i];
char te = char(temp);
Mes_out.push_back(te);
}
}
void DES_ALG::ASC_Bin(BITE * Data_Out,string Data_in,int Num) {
int i = 0;
for (; i < Num; i++) {
Data_Out[i] = (Data_in[i/8] >> (i % 8)) & 1;
}
}
void DES_ALG::BitsCopy(BITE *Data_Out,BITE *Data_In,int Num) {
int i = 0;
for (; i < Num; i++) {
Data_Out[i] = Data_In[i];
}
}
void DES_ALG::TableTrans(BITE * Date_Out,BITE *Data_In,const char *table,int Num) {
int i = 0;
static BITE temp[256] = { 0 };
for (; i < Num; i++) {
temp[i] = Data_In[table[i] - 1];
}
BitsCopy(Date_Out, temp, Num);
}
void DES_ALG::LoopMove(BITE * Data_In,int Len,int Num) {
static BITE Temp[256] = { 0 };
BitsCopy(Temp, Data_In, Num);
BitsCopy(Data_In, Data_In + Num, Len - Num);
BitsCopy(Data_In + Len - Num, Temp, Num);
}
void DES_ALG::CreSubKey(string Data_in) {
int i = 0;
static BITE KeyBit[64] = { 0 };
static bool* KiL = &KeyBit[0], * KiR = &KeyBit[28];
ASC_Bin(KeyBit, Data_in, 64);
TableTrans(KeyBit, KeyBit, PC1_Table, 56);
for (i = 0; i < 16; i++) {
LoopMove(KiL, 28, Move_Table[i]);
LoopMove(KiR, 28, Move_Table[i]);
TableTrans(SubKey[i], KeyBit, PC2_Table,48);
}
}
void DES_ALG::XOR(BITE * Data_Out,BITE * Data_In,int Num) {
int i = 0;
for (; i < Num; i++) {
Data_Out[i] = Data_Out[i] ^ Data_In[i];
}
}
void DES_ALG::S_change(BITE Data_Out[32],BITE Data_In[48]) {
int i, X, Y;
for (i = 0, X = 0, Y = 0; i < 8; Data_In += 6, i++) {
X = (Data_In[0] << 1) + Data_In[5];
Y = (Data_In[1] << 3) + (Data_In[2] << 2) + (Data_In[3] << 1) + Data_In[4];
ASC_Bin(Data_Out + i * 4, &S_Box[i][X][Y], 4);
}
}
void DES_ALG::F_change(BITE Data_In[32],BITE Data_Ki[48]) {
static bool MiR[48] = { 0 };
TableTrans(MiR, Data_In, E_Table, 48);
XOR(MiR, Data_Ki, 48);
S_change(Data_In, MiR);
TableTrans(Data_In, Data_In, P_Table, 32);
}
void DES_ALG::Enc_DES(BITE *Mes_Out,string Mes_In) {
int i = 0;
BITE temp[32] = { 0 };
BITE* MiL = &Mes_Out[0], * MiR = &Mes_Out[32];
ASC_Bin(Mes_Out, Mes_In, 64);
cout << "明文二进制串:"<<endl;
PrintBin(Mes_Out, 64);
TableTrans(Mes_Out, Mes_Out, IP_Table, 64);
for (; i < 16; i++) {
BitsCopy(temp, MiR, 32);
F_change(MiR, SubKey[i]);
XOR(MiR, MiL, 32);
BitsCopy(MiL, temp, 32);
}
TableTrans(Mes_Out, Mes_Out, IPR_Table, 64);
}
void DES_ALG::Dec_DES(string &Mes_Out,BITE *Mes_In) {
int i = 15;
BITE temp[32] = { 0 };
BITE MES_OUT[64] = { 0 };
BITE* MiL = &MES_OUT[0], * MiR = &MES_OUT[32];
TableTrans(MES_OUT, Mes_In, IP_Table, 64);
for (; i >=0; i--) {
BitsCopy(temp, MiL, 32);
F_change(MiL, SubKey[i]);
XOR(MiL, MiR, 32);
BitsCopy(MiR, temp, 32);
}
TableTrans(MES_OUT, MES_OUT, IPR_Table, 64);
cout << "解密后的二进制串:" << endl;
PrintBin(MES_OUT, 64);
Bin_ASC(Mes_Out, MES_OUT, 64);
}
void DES_ALG::DesEnter(string &Data_in,BITE **Data_Out, string key, int Mode, int dataLen=64) {
if (Mode == 1)
{
NumS = Data_in.size();
if (Data_in.size() % 8 != 0) {
for (int i = 0; i < 8 - (NumS % 8); i++) {
Data_in.push_back('C');
}
}
cout << "填充数据:"<<Data_in << endl;
GroupNum = Data_in.size() / 8;
CreSubKey(key);
for (int i = 0; i < GroupNum; i++) {
string GroupX = "";
for (int j = 0; j < 8; j++) {
GroupX.push_back(Data_in[i * 8 + j]);
}
cout << GroupX << endl;
Enc_DES(Data_Out[i], GroupX);
}
}
else {
for (int i = 0; i < GroupNum; i++) {
Dec_DES(Data_in, Data_Out[i]);
}
for (int i = 0; i < GroupNum * 8 - NumS; i++) {
Data_in.pop_back();
}
}
}
int main() {
string Mess_Out = "";
BITE** BITE_IO = new BITE * [N];
for (int i = 0; i < N; i++) {
BITE_IO[i] = new BITE[64];
}
string Mes = "";
cout << "请输入需要加密的明文:";
getline(cin, Mes);
string key = "";
cout << "请输入秘钥:";
getline(cin, key);
DES_ALG* DES = new DES_ALG;
cout << "开始加密——" << endl;
DES->DesEnter(Mes,BITE_IO, key, 1);
cout <<"加密后的二进制密文是:"<<endl;
for (int i = 0; i < DES->Get_GroupNUm();i++)
{
PrintBin(BITE_IO[i], 64);
}
DES->DesEnter(Mess_Out,BITE_IO, key, 0);
cout << "解密后的结果:" << Mess_Out << endl;
return 0;
}
- Numbertables.h 文件存储不会改变的表
#ifndef _TABLES_H_
#define _TABLES_H_
const char IP_Table[64] = {
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 char IPR_Table[64] = {
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
};
static char 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
};
static char 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
};
static char Move_Table[16] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
static char 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,34,33,48,
44,49,39,56,34,53,46,42,50,36,29,32
};
static char 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},
}
};
static char P_Table[32] = {
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
};
static bool SubKey[16][48] = { 0 };
#endif
- 代码参考https://www.cnblogs.com/ailx10/p/5303465.html