·好久没有写博客了,换句话说就是很久没有刷题了,从长沙回来,就被大大小小的考试文档弄的生活乱七八糟的,今年的期末考试仿佛来的更早了些,现在已经断断续续考了几门了,感觉都把刷题抛到脑后了,今天老师布置了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; }