📄 des.cpp
字号:
#include <fstream.h>
#include <math.h>
#include <string.h>
#include <conio.h>
//存放所有表的文件(次序跟下面声明顺序一样)
const char* alltables_file = "alltables.txt";
class DES
{
public:
DES(int skdata[]); //以skdata来初始化密钥
void SetPL(int pldata[]); //置明文值
void SetCI(int cidata[]); //置密文值
void GetPL(int pldata[]); //获取明文
void GetCI(int cidata[]); //获取密文
bool ReadTables(); //读表
void Crypt(); //DES核心算法
bool Encrypt(); //加密 返回是否加密成功
bool Decrypt(); //解密 返回是否解密成功
private:
int PL[64]; //明文
int CI[64]; //密文
int SK[64]; //密钥
int L[17][32]; //一轮输入的左32位
int R[17][32]; //一轮输入的右32位
int C[17][28]; //一轮中密钥的左28位
int D[17][28]; //一轮中密钥的右28位
int K[17][48]; //一轮中参与异或的密钥
int IPTable[64]; //初始置换表
int IIPTable[64]; //逆初始置换表
int ETable[48]; //扩充置换表
int PTable[32]; //置换函数表
int PC1Table[56]; //置换选择1表(密钥)
int PC2Table[48]; //置换选择2表(密钥)
int LBitTable[17]; //密钥每轮左移的位数表
int SBoxsTable[8][64]; //S盒表
};
DES::DES(int skdata[])
{
for(int i=0; i<64; i++)
SK[i] = skdata[i];
}
void DES::SetPL(int pldata[])
{
for(int i=0; i<64; i++)
PL[i] = pldata[i];
}
void DES::SetCI(int cidata[])
{
for(int i=0; i<64; i++)
CI[i] = cidata[i];
}
void DES::GetPL(int pldata[])
{
for(int i=0; i<64; i++)
pldata[i] = PL[i];
}
void DES::GetCI(int cidata[])
{
for(int i=0; i<64; i++)
cidata[i] = CI[i];
}
bool DES::ReadTables() //读表程序
{ //输入:同文件目录下的alltables.txt
ifstream input_file; //输出:为所有类成员表赋值,出错返回false,否则为true
char Tnames[20]; //表的名字(读入它用于过滤表中名字说明)
int i;
input_file.open(alltables_file);
if(!input_file) //打不开文件
{
cout<<"Can not open alltables file!"<<endl;
return false;
}
input_file>>Tnames;
for(i=0; i<64; i++)
{
input_file>>IPTable[i]; //读入初始置换表
IPTable[i]--; //把表中数据(1-64)转化为下标(0-63)
}
input_file>>Tnames;
for(i=0; i<64; i++)
{
input_file>>IIPTable[i]; //读入逆初始置换表
IIPTable[i]--; //把表中数据(1-64)转化为下标(0-63)
}
input_file>>Tnames;
for(i=0; i<48; i++)
{
input_file>>ETable[i]; //读入扩充置换表
ETable[i]--; //把表中数据(1-48)转化为下标(0-47)
}
input_file>>Tnames;
for(i=0; i<32; i++)
{
input_file>>PTable[i]; //读入置换函数表
PTable[i]--; //把表中数据(1-32)转化为下标(0-31)
}
input_file>>Tnames;
for(i=0; i<56; i++)
{
input_file>>PC1Table[i]; //读入置换选择1表
PC1Table[i]--; //把表中数据(1-56)转化为下标(0-55)
}
input_file>>Tnames;
for(i=0; i<48; i++)
{
input_file>>PC2Table[i]; //读入置换选择2表
PC2Table[i]--; //把表中数据(1-48)转化为下标(0-47)
}
input_file>>Tnames;
for(i=1; i<17; i++)
input_file>>LBitTable[i]; //读入密钥每轮左移的位数表 注意第0轮不用,下标1-16有用
input_file>>Tnames;
for(i=0; i<8; i++)
for(int j=0; j<64; j++) //读入S盒表
input_file>>SBoxsTable[i][j];
input_file.close();
return true;
}
void DES::Crypt()
{
int i,j; //用于循环计数(i主要用于轮数)
int T_ER[17][48]; //右明文扩充置换之后的暂存数组
int T_RK[17][48]; //T_ER与K异或之后的暂存数组
int T_SRK[17][32]; //T_RK经S盒代换之后的暂存数组
int T_PSRK[17][32]; //T_SRK经P置换之后的暂存数组
for(i=1; i<=16; i++) //开始16轮加密过程
{
for(j=0; j<32; j++) //第一步:Li = Ri-1
L[i][j] = R[i-1][j];
for(j=0; j<48; j++) //第二步:扩充置换******
T_ER[i][j] = R[i-1][ETable[j]];
for(j=0; j<48; j++) //第三步:PC-2置换******
{
if(PC2Table[j] < 28) K[i][j] = C[i][PC2Table[j]];
else K[i][j] = D[i][PC2Table[j]-28];
}
for(j=0; j<48; j++) //第四步:T_ER与K异或******
T_RK[i][j] = (T_ER[i][j] + K[i][j]) % 2;
int x=0, y=0; //第五步:S盒代换******
for(int box=0; box<8; box++) //x,y分别是每经一盒对应于T_RK和T_SRK要平移的位数
{
int row, col, value; //求出在S表中的行和列、以及对应坐标得出的S盒的值
row = T_RK[i][x]*2 + T_RK[i][x+5];
col = T_RK[i][x+1]*8 + T_RK[i][x+2]*4
+ T_RK[i][x+3]*2 + T_RK[i][x+4];
value = SBoxsTable[box][row*16 + col];
for(int bt=0; bt<4; bt++) //将value转化为二进制并赋值给T_SRK
{
int tpow = (int)pow(2, (3-bt));
T_SRK[i][bt+y] = value / tpow;
value = value % tpow;
}
x += 6; y += 4;
}
for(j=0; j<32; j++) //第六步:P置换******
T_PSRK[i][j] = T_SRK[i][PTable[j]];
for(j=0; j<32; j++) //第七步:T_PSRK与Li-1异或******
R[i][j] = (T_PSRK[i][j] + L[i-1][j]) % 2;
}
}
bool DES::Encrypt()
{
if(!ReadTables()) //数据读入失败
{
cout<<"Error! Data Loaded Fail!"<<endl;
return false;
}
int i;
int T_IPPL[64]; //明文初始置换之后的暂存数组
int T_PC1SK[56]; //密钥经PC1置换之后的暂存数组
for(i=0; i<64; i++) //******初始置换******
T_IPPL[i] = PL[IPTable[i]];
for(i=0; i<32; i++) //给L0与R0赋初值
{
L[0][i] = T_IPPL[i];
R[0][i] = T_IPPL[i+32];
}
for(i=0; i<56; i++) //******PC-1置换******
T_PC1SK[i] = SK[PC1Table[i]];
for(i=0; i<28; i++) //给C0与D0赋初值
{
C[0][i] = T_PC1SK[i];
D[0][i] = T_PC1SK[i+28];
}
for(i=1; i<=16; i++)
{
for(int j=0; j<LBitTable[i]; j++) //******各轮密钥生成******
{
for(int kk=0; kk<27; kk++) //本轮密钥左移LBitTable[i]位
{
C[i][kk] = C[i-1][kk+1];
D[i][kk] = D[i-1][kk+1];
}
C[i][27] = C[i-1][0];
D[i][27] = D[i-1][0];
}
}
Crypt(); //******16轮DES核心算法******
for(i=0; i<64; i++) //******把L16与R16交换后的值赋给准密文******
{
if(i<32) CI[i] = R[16][i];
else CI[i] = L[16][i-32];
}
return true;
}
bool DES::Decrypt()
{
if(!ReadTables()) //数据读入失败
{
cout<<"Error! Data Loaded Fail!"<<endl;
return false;
}
int i;
int T_PC1SK[56]; //密钥经PC1置换之后的暂存数组
int T_PL[64]; //准明文(还差逆初始置换)
for(i=0; i<32; i++) //给L0与R0赋初值
{
L[0][i] = CI[i];
R[0][i] = CI[i+32];
}
for(i=0; i<56; i++) //******PC-1置换******
T_PC1SK[i] = SK[PC1Table[i]];
for(i=0; i<28; i++) //给C0与D0赋初值
{
C[0][i] = T_PC1SK[i];
D[0][i] = T_PC1SK[i+28];
}
for(i=16; i>=1; i--)
{
for(int j=0; j<LBitTable[i]; j++) //******各轮密钥生成******
{
for(int kk=0; kk<27; kk++) //本轮密钥左移LBitTable[i]位
{
if(i == 16) //注意与加密密码下标反转(除第0个)
{
C[16][kk] = C[0][kk+1];
D[16][kk] = D[0][kk+1];
}
else{
C[i][kk] = C[i+1][kk+1];
D[i][kk] = D[i+1][kk+1];
}
}
if(i == 16)
{
C[16][27] = C[0][0];
D[16][27] = D[0][0];
}
else{
C[i][27] = C[i+1][0];
D[i][27] = D[i+1][0];
}
}
}
Crypt(); //******16轮DES核心算法******
for(i=0; i<64; i++) //******把L16与R16交换后的值赋给准明文******
{
if(i<32) T_PL[i] = R[16][i];
else T_PL[i] = L[16][i-32];
}
for(i=0; i<64; i++) //******准明文的逆初始置换******
PL[i] = T_PL[IIPTable[i]];
return true;
}
int* CharstoBits(int NN, char chs[]) //把一个字符串转化为ASCII码串
{
int n = NN * 8; //每个字符占8位
int* bs = new int [n+1];
int tvalue, tpow, x=0;
for(int i=0; i<NN; i++)
{
tvalue = (int) chs[i]; //求字符对应的ASCII码的十进制值
for(int j=0; j<8; j++) //十进制转化为二进制串
{
tpow = (int)pow(2, (7-j));
bs[x+j] = tvalue / tpow;
tvalue = tvalue % tpow;
}
x += 8;
}
bs[n] = '\0';
return bs;
}
char* BitstoChars(int NN, int bs[]) //把一个ASCII码串转化为字符串
{
int n = NN / 8; //每个字符占8位
char* chs = new char [n+1];
int tvalue, x=0;
for(int i=0; i<n; i++)
{
tvalue=0;
for(int j=0; j<8; j++)
tvalue += (int)bs[x+j] * pow(2, 7-j); //求出此ASCII码对应的十进制值
chs[i] = (char)tvalue; //将此值转为字符类型
x += 8;
}
chs[n] = '\0';
return chs;
}
/***********************DEMO2***************************/
void main() //显示程序
{
int* plain; //输入的明文指针
int* skey; //输入的密钥指针
int plshow[65]; //明文ASCII码数组
int cishow[64]; //密文ASCII码数组
int dplshow[65]; //解出的密文ASCII码数组
int i, num; //用于循环和计数
char* chshow; //用于显示字符串
char ch[8]; //用于输入暂存
cout<<"***正在运行DES加解密显示程序***"<<endl<<endl;
do{
cout<<"请输入要加密的串(8个字符):";
cin>>ch;
}while(strlen(ch) != 8); //串长必须为8个字符
plain = CharstoBits(8, ch); //转化为ASCII码串并作为明文输入
cout<<endl;
do{
cout<<"请输入要密钥(8个字符):";
cin>>ch;
}while(strlen(ch) != 8); //串长必须为8个字符
skey = CharstoBits(8, ch); //转化为ASCII码串并作为密钥输入
skey[64] = '\0';
DES en(skey); //加密过程 初始化数据
en.SetPL(plain);
en.GetPL(plshow);
plshow[64] = '\0';
cout<<endl<<"密钥(ASCII码):"; //显示密钥(ASCII码)
for(num=0, i=0; i<64; i++)
{
if(num%8 == 0) cout<<endl;
cout<<skey[i]<<" * ";
num++;
}
cout<<endl<<"明文(ASCII码):"; //显示明文(ASCII码)
for(num=0, i=0; i<64; i++)
{
if(num%8 == 0) cout<<endl;
cout<<plshow[i]<<" * ";
num++;
}
if( !en.Encrypt() ) //加密失败
{
cout<<endl<<"!!!!!!加密失败!!!!!!"<<endl;
return;
}
en.GetCI(cishow); //加密成功 获取密文
cout<<endl<<"\n.........加密中.........\n";
cout<<endl<<"密文:"; //显示密文串
chshow = BitstoChars(64, cishow);
cout<<chshow;
cout<<endl<<"密文(ASCII码):"; //显示密文(ASCII码)
for(num=0, i=0; i<64; i++)
{
if(num%8 == 0) cout<<endl;
cout<<cishow[i]<<" * ";
num++;
}
DES de(skey); //解密过程
de.SetCI(cishow);
if( !de.Decrypt() ) //解密失败
{
cout<<endl<<"!!!!!!解密失败!!!!!!"<<endl;
return ;
}
de.GetPL(dplshow); //解密成功 获取明文
cout<<endl<<"\n.........解密中.........\n";
cout<<endl<<"明文:"; //显示明文
chshow = BitstoChars(64, dplshow);
cout<<chshow;
cout<<endl;
cout<<"Press any key to Quit "<<endl;
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -