#include<stdio.h>
#include<stdlib.h>
void IP(int plaintext[]);//初始置换,传进来的是64位明文数组
void InversePermutation(int cipher[]);//逆初始置换
void ExtendAndPermutation(int RIn[]);//扩展置换,输入RIn为48位,后面16位为空
void XOR_48(int xor[], int Ki[]);//XOR 48位
void SBox(int S[]);//输入S盒为48位
void Permutation(int Pin[]);//置换P,32位数组输入
void XOR_32(int L[],int xor[]);//二者均为32位,xor[]保存异或结果
void Round(int bits[], int Ki[]);//bits为64位输入,经过函数后改变值成为输出,Ki为第i轮的密钥,轮函数
void PC1(int key[]);//key为64位,后8位被处理成0,前56位为置换选择的结果
void RingShiftLeft(int input[], int k);//input为56位输入,k为当前轮数-1
void RingShiftRight(int input[], int k);//input为56位输入,k为当前轮数-1
void PC2(int key[]);//输入为56位密钥,前48位更改为48位密钥,后8位置0
void exchange_32(int mid[]);//输入为64位数组
typedef struct node{
int plain[64];
struct node *link;
}LNode,*LinkList;
int main()
{
int mid[64];
char Input[16];
int key[64];
int midkey[64];
int midkey_56[56];
int midkey_56_2[56];
int midkey_48[48];
char KEY[16];
int q = 0;
int lunshu = 0;
char ch;
int res;
int haha;
int i;
int i1;
int k=0;//只在读取时用
int j=0;
LinkList head = NULL, p = NULL, r,Plain = NULL,b,c;
printf("请输入16进制密文与密钥,中间以空格分隔\n");
ch = getchar();
while (ch != ' ')//读取输入明文,16进制,转换为二进制储存于head链表中,每个链结点中有两个十六进制数,即64位二进制数
{
for (i = 0; i < 16; i++)//16位输入
{
Input[i] = ch;
if ((' ' == ch) && (i!=15) )//如果不满足16位,也就是8位十六进制输入,以最后一位补全
{
for (i = 8; i < 16; i++)
Input[i] = Input[i - 1];
break;
}
ch = getchar();
}
i = 0;
k = 0;
while (i < 16){//转换为2进制,暂存于mid[]中
switch (Input[i++])
{
case '0':mid[k++] = 0; mid[k++] = 0; mid[k++] = 0; mid[k++] = 0; break;
case '1':mid[k++] = 0; mid[k++] = 0; mid[k++] = 0; mid[k++] = 1; break;
case '2':mid[k++] = 0; mid[k++] = 0; mid[k++] = 1; mid[k++] = 0; break;
case '3':mid[k++] = 0; mid[k++] = 0; mid[k++] = 1; mid[k++] = 1; break;
case '4':mid[k++] = 0; mid[k++] = 1; mid[k++] = 0; mid[k++] = 0; break;
case '5':mid[k++] = 0; mid[k++] = 1; mid[k++] = 0; mid[k++] = 1; break;
case '6':mid[k++] = 0; mid[k++] = 1; mid[k++] = 1; mid[k++] = 0; break;
case '7':mid[k++] = 0; mid[k++] = 1; mid[k++] = 1; mid[k++] = 1; break;
case '8':mid[k++] = 1; mid[k++] = 0; mid[k++] = 0; mid[k++] = 0; break;
case '9':mid[k++] = 1; mid[k++] = 0; mid[k++] = 0; mid[k++] = 1; break;
case 'a':mid[k++] = 1; mid[k++] = 0; mid[k++] = 1; mid[k++] = 0; break;
case 'b':mid[k++] = 1; mid[k++] = 0; mid[k++] = 1; mid[k++] = 1; break;
case 'c':mid[k++] = 1; mid[k++] = 1; mid[k++] = 0; mid[k++] = 0; break;
case 'd':mid[k++] = 1; mid[k++] = 1; mid[k++] = 0; mid[k++] = 1; break;
case 'e':mid[k++] = 1; mid[k++] = 1; mid[k++] = 1; mid[k++] = 0; break;
case 'f':mid[k++] = 1; mid[k++] = 1; mid[k++] = 1; mid[k++] = 1; break;
default:break;
}
}
p = (LinkList)malloc(sizeof(LNode));
for (i = 0; i < 64; i++)
{
p->plain[i] = mid[i];
}
p->link = NULL;
if (head == NULL)
head = p;
else
r->link = p;
r = p;
}
do{//吃掉空格
ch = getchar();
} while (ch == ' ');
//get key
while (ch != '\n')//读取输入密钥,16进制
{
for (i = 0; i < 16; i++)//16位输入
{
KEY[i] = ch;
ch = getchar();
}
i = 0;
k = 0;
while (i < 16){//转换为2进制,暂存于mid[]中
switch (KEY[i++])
{
case '0':key[k++] = 0; key[k++] = 0; key[k++] = 0; key[k++] = 0; break;
case '1':key[k++] = 0; key[k++] = 0; key[k++] = 0; key[k++] = 1; break;
case '2':key[k++] = 0; key[k++] = 0; key[k++] = 1; key[k++] = 0; break;
case '3':key[k++] = 0; key[k++] = 0; key[k++] = 1; key[k++] = 1; break;
case '4':key[k++] = 0; key[k++] = 1; key[k++] = 0; key[k++] = 0; break;
case '5':key[k++] = 0; key[k++] = 1; key[k++] = 0; key[k++] = 1; break;
case '6':key[k++] = 0; key[k++] = 1; key[k++] = 1; key[k++] = 0; break;
case '7':key[k++] = 0; key[k++] = 1; key[k++] = 1; key[k++] = 1; break;
case '8':key[k++] = 1; key[k++] = 0; key[k++] = 0; key[k++] = 0; break;
case '9':key[k++] = 1; key[k++] = 0; key[k++] = 0; key[k++] = 1; break;
case 'a':key[k++] = 1; key[k++] = 0; key[k++] = 1; key[k++] = 0; break;
case 'b':key[k++] = 1; key[k++] = 0; key[k++] = 1; key[k++] = 1; break;
case 'c':key[k++] = 1; key[k++] = 1; key[k++] = 0; key[k++] = 0; break;
case 'd':key[k++] = 1; key[k++] = 1; key[k++] = 0; key[k++] = 1; break;
case 'e':key[k++] = 1; key[k++] = 1; key[k++] = 1; key[k++] = 0; break;
case 'f':key[k++] = 1; key[k++] = 1; key[k++] = 1; key[k++] = 1; break;
default:break;
}
}
}
p = head;
while (p != NULL)
{
for (i1 = 0; i1 < 64; i1++)
{
mid[i1] = p->plain[i1];
}
for (i1 = 0; i1 < 64; i1++)
{
midkey[i1] = key[i1];
}
IP(mid);//初始置换
PC1(midkey);//置换选择1,midkey前56位有效
for (q = 0; q < 56; q++)
midkey_56[q] = midkey[q];
for(lunshu = 0;lunshu < 16; lunshu++)
RingShiftLeft(midkey_56, lunshu);
for (lunshu = 0; lunshu < 16; lunshu++)//16轮轮函数处理
{
for (q = 0; q < 56; q++)//将循环左移结果拷贝,留着原来的结果midkey_56进行下一次循环左移
midkey_56_2[q] = midkey_56[q];
PC2(midkey_56_2);
for (q = 0; q < 48; q++)//得到48位密钥
midkey_48[q] = midkey_56_2[q];
Round(mid, midkey_48);
RingShiftRight(midkey_56, lunshu);
}
exchange_32(mid);
InversePermutation(mid);
b = (LinkList)malloc(sizeof(LNode));
for (i = 0; i < 64; i++)
{
b->plain[i] = mid[i];
}
b->link = NULL;
if (Plain == NULL)
Plain = b;
else
c->link = b;
c = b;
p = p->link;
}
b = Plain;
while (b != NULL)
{
for (i = 0; i < 64; )
{
haha = 8;
res = 0;
for (k = 0; k < 4; k++)
{
res = res + haha*(b->plain[i++]);
haha = haha / 2;
}
switch (res)//输出为16进制
{
case 0:printf("0"); break;
case 1:printf("1"); break;
case 2:printf("2"); break;
case 3:printf("3"); break;
case 4:printf("4"); break;
case 5:printf("5"); break;
case 6:printf("6"); break;
case 7:printf("7"); break;
case 8:printf("8"); break;
case 9:printf("9"); break;
case 10:printf("a"); break;
case 11:printf("b"); break;
case 12:printf("c"); break;
case 13:printf("d"); break;
case 14:printf("e"); break;
case 15:printf("f"); break;
}
}
b = b->link;
}
printf("\n");
return 0;
}
void exchange_32(int mid[])
{
int mid1[32];
int i;
for(i = 0;i<32;i++)
{
mid1[i] = mid[i];
}
for(i = 32;i<64;i++)
{
mid[i-32]=mid[i];
}
for(i = 32;i<64;i++)
{
mid[i] = mid1[i-32];
}
}
void IP(int plaintext[])//初始置换,传进来的是64位明文数组
{
int mid[8][8];
int i = 0;
int j = 0;
int k = 0;
for (i = 7; i >= 0; i--)
{
mid[4][i] = plaintext[j++];
mid[0][i] = plaintext[j++];
mid[5][i] = plaintext[j++];
mid[1][i] = plaintext[j++];
mid[6][i] = plaintext[j++];
mid[2][i] = plaintext[j++];
mid[7][i] = plaintext[j++];
mid[3][i] = plaintext[j++];
if (j == 64)
break;
}
j = 0;
for (i = 0; i < 8; i++)
{
for (k = 0; k < 8; k++)
{
plaintext[j++] = mid[i][k];
}
}
}
void InversePermutation(int cipher[])//逆初始置换
{
int mid[8][8];
int i = 0;
int j = 0;
int k = 0;
for (i = 1; i != 8; i = (i + 2) % 9)//i做列
{
for (j = 7; j >= 0; j--)//j做行
{
mid[j][i] = cipher[k++];
}
}
k = 0;
for (j = 0; j < 8; j++)//j做行
{
for (i = 0; i < 8; i++)//i做列
{
cipher[k++] = mid[j][i];
}
}
}
void ExtendAndPermutation(int RIn[])//扩展置换,输入RIn为48位,后面16位为空
{
int mid[8][6];
int i = 0;
int j = 0;
int p = 0;
for (i = 0; i < 8; i++)//行
{
for (j = 1; j <