DES 算法 信息论与编码

·好久没有写博客了,换句话说就是很久没有刷题了,从长沙回来,就被大大小小的考试文档弄的生活乱七八糟的,今年的期末考试仿佛来的更早了些,现在已经断断续续考了几门了,感觉都把刷题抛到脑后了,今天老师布置了DES算法,是考试的一部分,写了一段很挫的代码,觉得也算是进行了代码的练习了吧!看看也是学过信息论的人啊!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<climits>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define repf(i,a,b) for(int i=(a); i<=(b); ++i)
#define repd(i,a,b) for(int i=(a); i>=(b); --i)
#define N 64
#define ll long long
#define M (1<<27)
int trans11[65]={ 
	0,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
};
int trans12[65]={//逆置换的
	0,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,  38,
	35,  3,  43,  11,  51,  19,  59,  27,
	34,  2,  42,  10,  50,  18,  58,  26,
	33,  1,  41,  9,  49,  17,  57,   25
};	
int trans21[57]={//置换选择1
	0,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
};	
int trans22[49]={//置换选择2
	0,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 add1[49]={
	0,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
};	
int submit[8][4][16]={//增加0是为了占位置的
	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	
};
int P[33]={
	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
};
int shift[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
int c,d;
void produce()//生成初始的c和d的
{
	int a[65];//这里的不是很明白的
	srand(time(0));//生成密钥源的
	repf(i,1,64) a[i]=rand()%2;//随机生成密钥源的
	repf(i,1,56) swap(a[i],a[trans21[i]]);//进行置换1的
	c=d=0;
	repf(i,1,28) c=c*2+a[i];
	repf(i,29,56) c=d*2+a[i];
}
void shiftfun(int ct)//c和d都为28位的数字的
{
	int x=ct;//M为2的27次方的
	while(x--)
		c=(c%M)<<1+c/M;
	x=ct;
	while(x--)
		d=(d%M)<<1+c/M;
}
int tran()//c和d的56位变为48位的
{
	int a[57];
	int x=c,y=d;
	repd(i,28,1) a[i]=x%2,x/=2;
	repd(i,56,29) a[i]=y%2,y/=2;
	repf(i,1,48) swap(a[i],a[trans22[i]]);
	int ans=0;
	repf(i,1,48) ans=ans*2+a[i];
	return ans;
}
ll add(ll x)//将r扩冲为44位的
{
	ll ans=0;
	int a[33];
	repd(i,32,1) a[i]=x%2,x/=2;
	repf(i,1,48) ans=ans*2+a[add1[i]];
	return ans;
}
ll del(ll ans)
{
	int a[65];//ans为48位,分为8份的
	repd(i,7,0)
	{
		int col=0,row=0;
		col=ans%2,ans=ans>>1;
		int k=1;
		rep(j,4) row+=(ans%2*k),ans=ans>>1,k=k<<1;
		col+=((ans%2)<<1),ans=ans>>1;
		a[i]=submit[i][row][col];
	}
	ans=0;
	rep(i,8) ans=(ans<<4)+a[i];
	repd(i,32,1) a[i]=ans%2,ans/=2;
	repf(i,1,32) swap(a[i],a[P[i]]);
	ans=0;
	repf(i,1,32) ans=ans*2+a[i];
	return ans;
}
char solve(char s[])
{
	//初始置换
	repf(i,1,64) swap(s[trans11[i]],s[i]);
	ll l=0,r=0,tmp;

	//对l和r进行初始化
	repf(i,1,32) if(s[i]=='1') l=(l<<1)+1; else l=(l<<1);
	repf(i,33,N) if(s[i]=='1') r=(r<<1)+1; else r=(l<<1);
//	cout<<l<<" "<<r<<endl;getchar();
	//进行循环的
	produce();//生成初始的56为密钥
	//分为c和d的
	rep(i,16)
	{
		shiftfun(i);//对c和d进行移位的
		ll x=tran();//将c和d的56转换为48位的
		//cout<<x<<endl;getchar();
		ll r0=add(r);//将r扩充为48为的,
		ll ans=r0^x;//获得抑或的结果的
		ll r1=del(ans);//将48位的转换为32位的
        l=r;
		r=r1;
	}
	repd(i,32,1) s[i]=l%2,l/=2;
	repd(i,64,33) s[i]=r%=2,r/=2;
	repf(i,1,N) swap(s[i],s[trans12[i]]);
	repf(i,1,N) printf("%d",s[i]);
	printf("\n");
}

int main()
{
	freopen("in.txt","r",stdin);
	char s[66];
//	while(true)//输入64位的字符串
	{
		repf(i,1,N) scanf("%c",&s[i]);
        solve(s);
	}
	return 0;
}


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡定的小Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值