#include <iostream>
#include <string>
using namespace std;
//左移位数表
const int L[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//PC-1
const int PC_1[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};
//PC-2
const int PC_2[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,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32};
int Setkey[16][48]={0};
//置换IP矩阵
const int IP[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};
//置换IP-1矩阵
const int IP_1[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};
//E变化矩阵
const int E[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};
//S盒置换
const int S[8][64]={
//S1
{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,15,10, 0, 6,13},
//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},
//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},
//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},
//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},
//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},
//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},
//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}
};
//P盒
const int P[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};
void ChangeIP(int a[64],int b[64],const int p[64])//P为置换的矩阵
{
for(int i=0;i<64;i++)
b[i]=a[p[i]-1];
}
//循环左移
void move(int a[28],int i)
{
int m=L[i];
int x=a[0];
int y=a[1];
for(int j=0;j<28-m;j++)
a[j]=a[j+m];
if(m==1)
a[27]=x;
else
{
a[26]=x;
a[27]=y;
}
}
//产生Ki
void SetKey(int key[64])
{
int i,j;
int C[28],D[28],E[56];
int change_key[56];
for(i=0;i<56;i++) //PC-1调整顺序
change_key[i]=key[PC_1[i]-1];
for(i=0;i<28;i++)
{
C[i]=change_key[i];
D[i]=change_key[i+28];
}
for(i=0;i<16;i++)
{
//进行循环移位
move(C,i);
move(D,i);
for(j=0;j<28;j++)
{
E[j]=C[j];
E[j+28]=D[j];
}
for(j=0;j<48;j++) //PC-2调整顺序
Setkey[i][j]=E[PC_2[j]-1];
}
}
//令a=b的函数
void copy(int a[32],int b[32])
{
for(int i=0;i<32;i++)
a[i]=b[i];
}
//将b矩阵分解成L,R两个矩阵
void resolve(int L[32],int R[32],const int b[64])
{
for(int i=0;i<32;i++)
{
L[i]=b[i];
R[i]=b[i+32];
}
}
//将L,R两个矩阵合成b矩阵
void compose(const int L[32],const int R[32],int b[64])
{
for(int i=0;i<32;i++)
{
b[i]=L[i];
b[i+32]=R[i];
}
}
//S盒代替
void S_function(const int R1[48],int F[32])
{
for(int i=0;i<8;i++)
{
int x=R1[i*6]*2+R1[i*6+5]+1;
int y=R1[i*6+1]*8+R1[i*6+2]*4+R1[i*6+3]*2+R1[i*6+4]+1;
int m=S[i][(x-1)*16+y-1];
for (int k=3;k>=0;k--)
{
F[i*4+k]=m%2;
m=m/2;
}
}
}
//加密
void quan1(int m[64])
{
int b[64]; //置换IP后的数组
int i;
ChangeIP(m,b,IP);
int L[32];
int R[32];
int R2[32];
int F[32]; //用于在圈函数中寄存S盒变化的R
int R1[48]; //存放R扩展变换后的
resolve(L,R,b);
for (int j=0;j<16;j++) //16次圈变换
{
copy(R2,R);
for(i=0;i<48;i++) //R的扩展变化+异或Ki
{
R1[i]=R[E[i]-1]^Setkey[j][i];;
}
S_function(R1,F);
for (i=0;i<32;i++)
{
R[i]=F[P[i]-1]^L[i];
L[i]=R2[i];
}
}
compose(L,R,b);
ChangeIP(b,m,IP_1);
}
//解密
void quan2(int m[64])
{
int b[64]; //置换IP后的数组
int i;
ChangeIP(m,b,IP);
int L[32];
int R[32];
int R2[32];
int F[32]; //用于在圈函数中寄存S盒变化的R
int R1[48]; //存放R扩展变换后的
resolve(L,R,b);
for (int j=0;j<16;j++) //16次圈变换
{
copy(R2,R);
copy(R,L);
for(i=0;i<48;i++) //R的扩展变化+异或Ki
{
R1[i]=R[E[i]-1]^Setkey[15-j][i];
}
S_function(R1,F);
for(i=0;i<32;i++)
{
L[i]=R2[i]^F[P[i]-1];
}
}
compose(L,R,b);
ChangeIP(b,m,IP_1);
}
//将10进制变为2进制存放到a[64]中
void GetBit(const string str,int a[64])
{
for (int i=0;(i!=str.size())&&(i<8);i++)
{
if (i%8==0)
{
for (int j=0;j<64;j++)
{
a[j]=0;
}
}
int x=str[i];
int y=i%8;
for (int j=7;j>=0;j--)
{
a[y*8+j]=x%2;
x=x/2;
}
}
}
//将2进制变为10进制
void GetDec(const int a[64],char str[8])
{
for (int i=0;i<8;i++)
{
int x=0;
int count=1;
for (int j=7;j>=0;j--)
{
x+=a[i*8+j]*count;
count*=2;
}
str[i]=(char)x;
}
}
int main(void)
{
string str_key;
cout<<"请输入密钥:";
cin>>str_key;
int key[64]={0};
GetBit(str_key,key);
SetKey(key);
string str_plaintxt;
cout<<"请输入明文:";
cin>>str_plaintxt;
int plaintxt[64]={0};
GetBit(str_plaintxt,plaintxt);
quan1(plaintxt);
char str_crpty[8]={0};
GetDec(plaintxt,str_crpty);
cout<<"密文:";
for(int i=0;i<8;i++)
{
cout<<str_crpty[i];
}
cout<<endl;
quan2(plaintxt);
char str_decrpty[8]={0};
GetDec(plaintxt,str_decrpty);
cout<<"明文解:";
for(int i=0;i<8;i++)
{
cout<<str_decrpty[i];
}
cout<<endl;
return 0;
}
DES
最新推荐文章于 2024-08-19 20:40:29 发布