#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int pc1[57]=
{-1,
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 bit_lmv[17]={-1,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
int pc2[49]=
{
-1,
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 ip[65]=
{
-1,
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 e[49]=
{
-1,
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 s[32][16]=
{
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]=
{
-1,
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 fip[65]=
{
-1,
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
};
int key[65]=
{-1,0,0,0,1,0,0,1,1 ,0,0,1,1,0,1,0,0, 0,1,0,1,0,1,1,1 ,0,1,1,1,1,0,0,1,
1,0,0,1,1,0,1,1, 1,0,1,1,1,1,0,0, 1,1,0,1,1,1,1,1 ,1,1,1,1,0,0,0,1};
int tmp[57];
int K[49];
void get_key(int time)
{
if(time==1) for(int i=1;i<=56;i++){tmp[i]=key[pc1[i]];}
int k=1;
while(k<=bit_lmv[time])
{
int o=tmp[1];
for(int i=1;i<=27;i++) {tmp[i]=tmp[i+1];}
tmp[28]=o;
k++;
}
k=1;
while(k<=bit_lmv[time])
{
int o=tmp[29];
for(int i=29;i<=55;i++) {tmp[i]=tmp[i+1];}
tmp[56]=o;
k++;
}
for(int i=1;i<=48;i++){K[i]=tmp[pc2[i]];}
}
int M[65]=
{-1,
0,0,0,0, 0,0,0,1, 0,0,1,0, 0,0,1,1, 0,1,0,0, 0,1,0,1, 0,1,1,0, 0,1,1,1,
1,0,0,0, 1,0,0,1, 1,0,1,0, 1,0,1,1, 1,1,0,0, 1,1,0,1, 1,1,1,0, 1,1,1,1
};
int L[33],R[33];
int E[48];
int F[33];
void encry(int time,int type)
{
if(time==1)
{
for(int i=1;i<=32;i++) {L[i]=M[ip[i]];}
for(int i=33;i<=64;i++) {R[i-32]=M[ip[i]];}
}
for(int i=1;i<=48;i++) E[i]=R[e[i]];
int tmxor[49];
if(type) for(int i=1;i<=17-time;i++) get_key(i);
else get_key(time);
for(int i=1;i<=48;i++)
{
tmxor[i]=E[i]^K[i];
}
int k=1,k1=1,k2=1,tmpF[33];
while(k<=48)
{
int r=tmxor[k]*2+tmxor[k+5]+(k2-1)*4;
int l=tmxor[k+4]+tmxor[k+3]*2+tmxor[k+2]*4+tmxor[k+1]*8;
int tmx=s[r][l];
for(int i=k1+3;i>=k1;i--)
{
tmpF[i]=tmx%2;
tmx=tmx/2;
}
k=k+6;k1=k1+4;k2++;
}
for(int i=1;i<=32;i++)
{
F[i]=tmpF[p[i]];
}
int tmy[33];
for(int i=1;i<=32;i++){tmy[i]=R[i];}
for(int i=1;i<=32;i++){R[i]=L[i]^F[i];}
for(int i=1;i<=32;i++){L[i]=tmy[i];}
}
int t_ans[65],ans[65];
char str[17],k_str[17];
void init()
{
unsigned long long value=0,pow=1;
for(int i=16;i>=1;i--)
{
if(str[i]>='0'&&str[i]<='9') value=value+(str[i]-'0')*pow;
else value=value+(str[i]-'A'+10)*pow;
pow=pow*16;
}
for(int i=64;i>=1;i--)
{
M[i]=value%2;
value=value/2;
}
value=0,pow=1;
for(int i=16;i>=1;i--)
{
if(k_str[i]>='0'&&k_str[i]<='9') value=value+(k_str[i]-'0')*pow;
else value=value+(k_str[i]-'A'+10)*pow;
pow=pow*16;
}
for(int i=64;i>=1;i--)
{
key[i]=value%2;
value=value/2;
}
}
char pto[17]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void tran()
{
char prln[17];
unsigned long long value=0,pow=1;
for(int i=64;i>=1;i--)
{
value=value+t_ans[i]*pow;
pow=pow*2;
}
for(int i=15;i>=0;i--)
{
prln[i]=pto[value%16];
value=value/16;
}
prln[16]='\0';
printf("%s\n",prln);
}
int type;
void _random()
{
srand((unsigned)time(NULL));
type=0;
for(int i=1;i<=16;i++) str[i]=pto[rand()%16],k_str[i]=pto[rand()%16];
printf("%s %s\n",str+1,k_str+1);
}
int main()
{
_random();
//scanf("%s%s%d",str+1,k_str+1,&type);
init();
for(int i=1;i<=16;i++) encry(i,type);
for(int i=1;i<=32;i++) ans[i]=R[i];
for(int i=33;i<=64;i++) ans[i]=L[i-32];
for(int i=1;i<=64;i++) t_ans[i]=ans[fip[i]];
//for(int i=1;i<=64;i++) printf("%d",t_ans[i]);
tran();
return 0;
}
/*
明文:0123456789ABCDEF
-0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
密钥:133457799BBCDFF1
-00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001
密文:85E813540F0AB405
-10000101 11101000 00010011 01010100 00001111 00001010 10110100 00000101
*/