DES

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值