📄 des.cpp
字号:
#include<stdio.h>
#include<string.h>
#include"des_encode.h"
int key[16][48];
char str[8];
char filename[15];
void main() //main function
{
int i;
printf("请输入你所需的项目:\n1.加密\t2.解密\n");
scanf("%d",&i);
if(i==1){
getchar();
EncodeMain();
}
else if(i==2){
getchar();
DecodeMain();
}
else {printf("输入错误\n");}
}
void EncodeMain() //EncodeMain function
{
int i;
char keychar[8];
int key2[8];
int strkey[8];
printf("\n请输入8个要加密的字符:\n");
for(i=0;i<8;i++)
scanf("%c",&str[i]);//将要加密的字符储存到str
getchar();
for(i=0;i<8;i++)
strkey[i]=str[i];
printf("\n请输入密钥(8个字符):\n");
for(i=0;i<8;i++)
scanf("%c",&keychar[i]);//keychar是密码
for(i=0;i<8;i++)
key2[i]=keychar[i];
getchar();
Encode(strkey,key2);
}
void DecodeMain()
{
int i;
char keychar[8];
int key2[8];
int strkey[8];
printf("\n\n清输入解密密码\n");
for(i=0;i<8;i++)
scanf("%c",&keychar[i]);
for(i=0;i<8;i++)
key2[i]=keychar[i];
Decode(strkey,key2);
for(i=0;i<8;i++)
str[i]=strkey[i];
printf("\n明文为:");
for(i=0;i<8;i++)
printf("%c",str[i]);
printf("\n\n");
}
void Encode(int *str,int *keychar)
{ //encode: input 8 chars,8 keychars
int lData[32],rData[32],temp[32],rDataP[48];
int i,j;
keyBuild(keychar);
EncodeData(lData,rData,str);
for(i=0;i<16;i++){
for(j=0;j<32;j++)
temp[j]=rData[j];
F(rData,key[i]);//交过去的参数是行指针
for(j=0;j<32;j++){
rData[j]=rData[j]^lData[j];
}//得到的32位再与lData0做异或运算作为下一轮的rData1,这一轮的lData0则成为下一轮的lData1
for(j=0;j<32;j++)
lData[j]=temp[j];
}
FILE *fp;
int k;
char ch;
printf("\n请输入所保存文件的文件名:\n");
scanf("%s",filename);
if((fp=fopen(filename,"wb+"))==NULL)
printf("文件写入错误,数据写入失败\n");
ch=getchar();//用于接受在sacnf语句时最后输入的回车
for(k=0;k<32;k++){
ch=rData[k];
fputc(ch,fp);
}
for(k=0;k<32;k++){
ch=lData[k];
fputc(ch,fp);
}
fclose(fp);
printf("\n文件已经保存成功,文件名为:%s\n",filename);
DecodeData(str,rData,lData);
}
void keyBuild(int *keychar)
{ //create key array
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];//将midkey 顺序打乱并储存再midkey2中 注意:只取了midkey的56位 没有取到midkey的第8 16 24 32 40 48 56 64(23)位
for(i=0;i<16;i++)
keyCreate(midkey2,movebit[i],i);
}
void StrtoBin(int *midkey,int *keychar){ //change into binary将keychar转换成二进制并储存再midkey中
int trans[8],i,j,k,n;
n=0;
for(i=0;i<8;i++){
j=0;
while(keychar[i]!=0){
trans[j]=keychar[i]%2;
keychar[i]=keychar[i]/2;
j++;
}
for(k=j;k<8;k++)trans[k]=0;
for(k=0;k<8;k++)
midkey[n++]=trans[7-k];
}
}
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];//midkey2数组的前25位都等于其后面的第二位,即所有数向左移动二位而midkey2[26]midkey[27]不变
midkey2[i+28]=midkey2[i+30];//midkey2数组从第28个数开始,每个数字都等于其后面的第二个数,即每个数向左移动两位,midkey2[54]midkey[55]不变
}
midkey2[26]=temp[0];midkey2[27]=temp[1];//将midkey2[26]midkey[27]分别赋值成原先的midkey2[0]midkey2[1]
midkey2[54]=temp[2];midkey2[55]=temp[3];//将midkey2[54]midkey[55]分别赋值成原先的midkey2[28]midkey2[29]
}
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];
}//如果movebit[i]==1则类似于上个循环,midkey[27]=midkey[0] midkey[55]=midkey[28]其他的顺次向前面移动一位
for(i=0;i<48;i++)
key[n][i]=midkey2[PC2[i]-1];//将所有转换过的midkey[2]数组打乱后存于key[16][48]中,其中一共有16个midkey2矩阵
}
void EncodeData(int *lData,int *rData,int *str)
{ //encodedata function
int i,j,temp[8],lint,rint;
int data[64];
lint=0,rint=0;
for(i=0;i<4;i++){//将所要加密的数据的前4位转化成二进制,储存在lData[32]中
j=0;
while(str[i]!=0){
temp[j]=str[i]%2;
str[i]=str[i]/2;
j++;
}
while(j<8)temp[j++]=0;
for(j=0;j<8;j++)
lData[lint++]=temp[7-j];
j=0;
while(str[i+4]!=0){//将所要加密的数据的后4位转化成二进制,储存在rData[32]中
temp[j]=str[i+4]%2;
str[i+4]=str[i+4]/2;
j++;
}
while(j<8)temp[j++]=0;
for(j=0;j<8;j++)rData[rint++]=temp[7-j];
}
for(i=0;i<32;i++){
data[i]=lData[i];
data[i+32]=rData[i];
}
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];
}
}
void F(int *rData,int *key)
{ //F function
int i,rDataP[48];
Expand(rData,rDataP);
for(i=0;i<48;i++){
rDataP[i]=rDataP[i]^key[i];// printf("%10d",rDataP[i]);if((i+1)%6==0)printf("\n");
}//E(A)与K作异或运算,结果是rDataP(=B)
ExchangeS(rDataP,rData);//对B
ExchangeP(rData);//结果F(rdata0,K1),得到的32位再与lData0做异或运算作为下一轮的rData1,这一轮的lData0则成为下一轮的lData1
}
void Expand(int *rData,int *rDataP){ //Expand function将rData由32位选择拓展运算至48位,记为E(A)
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];
liney=(rDataP[i+1]<<3)+(rDataP[i+2]<<2)+(rDataP[i+3]<<1)+rDataP[i+4];//将rDataP分成8组每组6位,将line[x]liney[y]作为参数传与于s盒中 x取值范围是0到3 y是0到15 因为s是8*4*16
FillBin(rData,n,s[n][linex][liney]);
}
}
void ExchangeP(int *rData){ //P change
int i,temp[32];
for(i=0;i<32;i++)
temp[i]=rData[i];
for(i=0;i<32;i++)
rData[i]=temp[P[i]-1];
}
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++){
temp[i]=s%2;
s=s/2;
}
for(i=0;i<4;i++)
rData[n*4+i]=temp[3-i];
}
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++){//对64位数字rData16,lData16施行初等变换IP1的逆变换IP2
lData[i]=data[IP2[i]-1];
rData[i]=data[IP2[i+32]-1];
}
for(i=0;i<32;i++){////??????
a=(lData[i]&0x1)+(a<<1);
b=(rData[i]&0x1)+(b<<1);
if((i+1)%8==0){
str[i/8]=a;a=0;//printf("%d",i/8);
str[i/8+4]=b;b=0;//printf("%d",i/8+4);
}
}
}
void Decode(int *str,int *keychar){ //decode :input 8 chars,8 keychars
int lData[32],rData[32],temp[32],rDataP[48];
int i,j;
FILE *fp;
int k;
char ch;
printf("\n请输入所解密文件的文件名:\n");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)
printf("\n文件读取错误,请检查文件是否存在\n");
ch=getchar();//用于接受在sacnf语句时最后输入的回车
for(k=0;k<32;k++){
lData[k]=fgetc(fp);
}
for(k=0;k<32;k++){
rData[k]=fgetc(fp);
}
fclose(fp);
keyBuild(keychar);
for(i=0;i<16;i++){
for(j=0;j<32;j++)
temp[j]=rData[j];
F(rData,key[15-i]);//解密时K的使用顺序和加密是K的顺序相反
for(j=0;j<32;j++){
rData[j]=rData[j]^lData[j];
}
for(j=0;j<32;j++){
lData[j]=temp[j];
}
}
DecodeData(str,rData,lData);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -