⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 des.cpp

📁 des源码 我学c语言做的 望多多支持 八位输入 文件输出 文件输入 八位输出
💻 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 + -