#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"HHHH.h"
int key[16][48];
int str[16]; //明文
int main() //main function
{
EncodeMain();
system("pause");
return 0;
}
void EncodeMain() //Encode Main function//编译密码的主要结构
{
int i;
int keychar[16];
int key2[16];
int strkey[16];
printf("请输入16个要加密的字符:\n");
for(i=0;i<16;i++)
scanf("%10x",&str[i]); //str[]存放明文
getchar();
for(i=0;i<16;i++)
strkey[i]=str[i]; //将明文复制到strkey[]中
printf("\n请输入密钥(16个字符):\n");
for(i=0;i<16;i++)
scanf("%10x",&keychar[i]); //keychar[]存放密钥
for(i=0;i<16;i++)
key2[i]=keychar[i]; //将密钥复制到key2[]中
getchar();
Encode(strkey,key2); //加密函数,strkey为明文地址,key2为密钥地址
printf("\n加密后十六进制密文是:\n");
for(i=0;i<16;i++)
printf("%10x",strkey[i]); //输出十六进制的密文
printf("\n\n清输入解密密码\n");
for(i=0;i<16;i++)
scanf("%10x",&keychar[i]); //keychar[]存放解密密钥
getchar();
for(i=0;i<16;i++)
key2[i]=keychar[i]; //将密钥复制到key2[]中
Decode(strkey,key2); //解密函数,strkey为密文地址,key2为密钥地址
for(i=0;i<16;i++)
printf("%10x",strkey[i]); //输出十六进制的明文
printf("\n\n");
}
//编排密钥
void keyBuild(int *keychar){ //create key array //创建密钥数组key[][]
int i,j;
int movebit[]={1,1,2,2,2,2,2,2,
1,2,2,2,2,2,2,1}; //循环左移的位数
int midkey2[56];
int midkey[64];
StrtoBin(midkey,keychar); //将代码转换成二进制的
for(i=0;i<56;i++)
midkey2[i]=midkey[PC1[i]-1]; //进行置换并将代码复制到midkey2中
for(i=0;i<16;i++) //得到十六轮代换的密钥
keyCreate(midkey2,movebit[i],i);
}
//将密钥转换成二进制的形式
void StrtoBin(int *midkey,int *keychar){ //change into binary
int trans[4],i,j,k,n;
n=0;
for(i=0;i<16;i++){
j=0; //记录转换的二进制的位数
while(keychar[i]!=0){ //将密钥中的每个字符转换成二进制的形式的逆序
trans[j]=keychar[i]%2;
keychar[i]=keychar[i]/2;
j++;
}
for(k=j ;k<4;k++)trans[k]=0; //转换的二进制数不足八位的后面补零
for(k=0;k<4;k++)
midkey[n++]=trans[3-k]; //将密钥中的字符完全转换成二进制的形式,其值与字符对应的ASCII码相等。
}
}
void keyCreate(int *midkey2,int movebit , int n){ //左移
int i,temp[4];
temp[0]=midkey2[0];
temp[1]=midkey2[1];
temp[2]=midkey2[28];
temp[3]=midkey2[29];
if(movebit==2){ //都左移两个位置
for(i=0;i<26;i++){
midkey2[i]=midkey2[i+2]; //2~28位循环左移两位
midkey2[i+28]=midkey2[i+30]; //31~56位循环左移两位
}
midkey2[26]=temp[0];midkey2[27]=temp[1]; //第1位移到27位,第2位移到28位
midkey2[54]=temp[2];midkey2[55]=temp[3];//第29位移到55位,第30位移到56位
}
else //左移一个位置
{ for(i=0;i<27;i++){ //都左移一位,方法同左移一位相同
midkey2[i]=midkey2[i+1];
midkey2[i+28]=midkey2[i+29];
}
midkey2[27]=temp[0];midkey2[55]=temp[2];
}
for(i=0;i<48;i++)
key[n][i]=midkey2[PC2[i]-1]; //再次置换得到48位的密钥
}
//进行IP转换得到L0和R0
void EncodeData(int *lData,int *rData,int *str){ //encodedata function
int i,j,temp[16],lint, rint; //int h;
int data[64];
lint=0,rint=0;
for( i =0;i<8;i++){ //把前四个字符转换成二进制的
j=0;
while(str[i]!=0){
temp[j]=str[i]%2;
str[i]=str[i]/2;
j++;
}
while (j<4)
temp [j++]=0;
for(j=0;j<4;j++)
lData[lint++]=temp[3-j];
j=0;
while(str[i+8]!=0){ //将后四个字符转换成二进制的形式
temp[j]=str[i+8]%2;
str[i+8]=str[i+8]/2;
j++;
}
while(j<4)temp[j++]=0;
for(j=0;j<4;j++)rData[rint++]=temp[3-j];
}
for(i=0;i<32;i++){ //将所有的字符的二进制放入data[]中
data[i]=lData[i];
data[i+32]=rData[i];
}
//进行IP转换,得到L0和R0
for(i=0;i<32;i++){
lData[i]=data[IP1[i]-1]; //printf("P1:%5d:%5d,%5d\n",IP1[i],lData[i],data[IP1[i]-1]);
rData[i]=data[IP1[i+32]-1];
}
}
//进行F函数处理
void F(int *rData,int *key){ //F function
int i,rDataP[48];
Expand(rData,rDataP); //E扩展
for(i=0;i<48;i++){
rDataP[i]=rDataP[i]^key[i]; // printf("%10d",rDataP[i]);if((i+1)%6==0)printf("\n");
} //密钥与明文的代码相加
ExchangeS(rDataP,rData); //S盒代换
ExchangeP(rData); //IP置换
}
//E扩展,将32位扩展到48位
void Expand(int *rData,int *rDataP){ //Expand function
int i;
for(i=0;i<48;i++)
rDataP[i]=rData[Ex[i]-1];
}
void ExchangeS(int *rDataP,int *rData){ //S-diagram change
int i,n,linex,liney;
linex=liney=0;
for(i=0;i<48;i+=6){
n=i/6; //printf("%10d\n",(rDataP[i]<<1));
linex=(rDataP[i]<<1)+rDataP[i+5]; //计算S盒中的行
liney=(rDataP[i+1]<<3)+(rDataP[i+2]<<2)+(rDataP[i+3]<<1)+rDataP[i+4];
//计算S盒中的列
FillBin(rData,n,s[n][linex][liney]);
}
}
//进行P置换
void ExchangeP(int *rData){ //P change
int i,temp[32];
for(i=0;i<32;i++)
temp[i]=rData[i]; //将原始数据复制到temp[]中
for(i=0;i<32;i++)
rData[i]=temp[P[i]-1]; //将置换后的数据存放在rData[]中
}
void FillBin(int *rData,int n,int s){ // data to binary;call by S-Diagram change function
int temp[4],i;
for(i=0;i<4;i++){ //将S盒中对应的数字转换成二进制形式
temp[i]=s%2;
s=s/2;
}
for(i=0;i<4;i++)
rData[n*4+i]=temp[3-i]; //将转换后的数据存放在rData[]中
}
void DecodeData(int *str,int *lData,int *rData){ //DecodeData from binary
int i;int a,b;int data[64];
a=0,b=0;
for(i=0;i<32;i++){
data[i]=lData[i];
data[i+32]=rData[i];
}
for(i=0;i<32;i++){
lData[i]=data[IP2[i]-1];
rData[i]=data[IP2[i+32]-1]; //进行最后一次IP转换
}
for(i=0;i<32;i++){ //将二进制转换成十六进制对应的字符的ASCII码
a=(lData[i]&0x1)+(a<<1);
b=(rData[i]&0x1)+(b<<1);
if((i+1)%4==0){
str[i/4]=a;a=0;//printf("%d",i/8);
str[i/4+8]=b;b=0;//printf("%d",i/8+4); //将转换后的代码存放在str[]中
}
}
}
void Encode(int *str,int *keychar){ //encode: input 8 chars,8 keychars
int lData[32],rData[32],temp[32],rDataP[48];
int X,i,j;
keyBuild(keychar);
EncodeData(lData,rData,str);
for(i=0;i<16;i++){ //进行十六轮迭代
printf("\nL%d\n",i);
for(X=0;X<32;X++)
printf("%d",lData[X]);
printf("\nR%d\n",i);
for(X=0;X<32;X++)
printf("%d",rData[X]);
for(j=0;j<32;j++)
temp[j]=rData[j];
F (rData,key[i]);
for(j=0;j<32;j++){ //进行相加得到下一个Ri
rData[j]=rData[j]^lData[j];
}
for(j=0;j<32;j++)
lData[j]=temp[j]; //得到下一个Li
}
for