| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
mx3y
10年前发布

C++简单数据加密算法实现加密和解密

/*    This is a program for Encryption and Decryption    This program uses the Simple Data Encryption Standard (SDES) Algorithm.    This Algo takes 8-bits of plaintext at a time and produces 8-bits of ciphertext.    It uses 10-bits of key for Encryption and Decryption.       Developed by : Vivek Kumar (vivek_kumar_bt@yahoo.co.in)        Created on : 31 March 2005     Last Modified on : 10 April 2005        Any sort of suggetions/comments are most welcome at vivek_kumar_bt@yahoo.co.in  */     #include<iostream.h>  #include<stdio.h>  #include<conio.h>  #include<string.h>  #include<stdlib.h>  #include<assert.h>  void mainmenu(int *);  void menuEn();  void menuDe();  int DoEnDe(int);     class SDES  {  private:      char KEY[11],K1[9],K2[9],IPOutput[9],InvIPOutput[9];      char F1Output[9],F2Output[9];      char INPUT_BIT[9],OUTPUT_BIT[9];     public:      unsigned char INPUT,OUTPUT;         SDES(char *key);      ~SDES();      void GenerateKeys();      char *Left_Shift(char *,int );      void conv_to_bits(unsigned char );      void IP(char *);      void InvIP(char *);      void DES_Encryption(unsigned char );      void DES_Decryption(unsigned char );      void Function_F(char *,char *,int );      char *EX_OR(char *,int );      char *SBOX0(char *);      char *SBOX1(char *);      void SDES::GetChar();  };  SDES::SDES(char *key)  //Initializes the object with 10-bits key  {      int i;      if (strlen(key)!=10)  //Checks for valid length key      {          printf("\nInValid Key-Length %s %d",key,strlen(key));          getch();          exit(1);      }      for (i=0;i<10;i++)  //Assigning the key privatly      {          KEY[i]=key[i];      }      KEY[10]='\0';      GenerateKeys(); //Key Genaration Starts. Output: (K1/K2)     }     void SDES::GenerateKeys()  {      int P10[10]={3,5,2,7,4,10,1,9,8,6};      //P10 permutation-array      char P10_OP[11];            //Output of P10 is to be stored here      int P8[8]={6,3,7,4,8,5,10,9};       //P8 permutation-array      char *P10LEFT,*pl,*pl1,*P10RIGHT,*pr,*pr1,*plpr;      int i;         /*P10 operation is done on main key*/      for (i=0;i<10;i++)          P10_OP[i]=KEY[P10[i]-1];         P10_OP[10]='\0';         /*Dividing 10-bit output of P10 operation into        two parts*/      for (i=0;i<5;i++)      {          P10LEFT[i]=P10_OP[i];          P10RIGHT[i]=P10_OP[i+5];      }      P10LEFT[5]='\0';      P10RIGHT[5]='\0';         pl=new char[6];      pr=new char[6];         /*Perform Left-Circular shift by 1 bit on the        two parts of P10 output*/      pl=Left_Shift(P10LEFT,1);      pr=Left_Shift(P10RIGHT,1);         /*Combine the above two parts after        the left-cicular operation into 'plpr' string*/      for (i=0;i<5;i++)      {          plpr[i]=pl[i];          plpr[i+5]=pr[i];      }      plpr[10]='\0';         /*Performing P8 Operation on plpr and assigning to K1*/      for (i=0;i<8;i++)          K1[i]=plpr[P8[i]-1];         K1[8]='\0'; //This is our first sub-key K1         /*Again performing Left-Circular-Shift(LCS) by 2 bits on        the output of previous Left-Cicular-Shift(LCS)*/      pl1=Left_Shift(pl,2);      pr1=Left_Shift(pr,2);         /*Combining the output of above LCS2 into 1 string*/      for (i=0;i<5;i++)      {          plpr[i]=pl1[i];          plpr[i+5]=pr1[i];      }      plpr[10]='\0';         /*Again performing P8 operation on the above combined        string*/      for (i=0;i<8;i++)      {          K2[i]=plpr[P8[i]-1];      }      K2[8]='\0'; //This is our second sub-key K2     }     /*Method to perform Left-Circular-Shift on bit-string*/  char *SDES::Left_Shift(char *bs,int n)  {      int length=strlen(bs);      char *char_ptr,firstbit,*str;         char_ptr = new char[length +1];      str=new char[length+1];      char_ptr=bs;         int i,j;      for (j=0;j<n;j++)      {          firstbit=char_ptr[0];             for (i=0;i<length-1;i++)          {              str[i]=char_ptr[i+1];          }          str[length-1]=firstbit;          char_ptr[length]='\0';          char_ptr=str;      }      char_ptr[length]='\0';      return(str);  }     /*Method to convert unsigned char to bit-string    For Ex. 1="00000001"*/  void SDES::conv_to_bits(unsigned char ch)  {      int i,bit;      INPUT_BIT[8]='\0';      for (i=7;i>=0;i--)      {          bit=ch%2;          ch=ch/2;             if (bit!=0)              INPUT_BIT[i]='1';          else              INPUT_BIT[i]='0';      }     }     /*Method to perform Initial-Permutation*/  void SDES::IP(char *input)  {      int IPArray[8]={2,6,3,1,4,8,5,7};      int i;      IPOutput[8]='\0';      for (i=0;i<8;i++)      {          IPOutput[i]=input[IPArray[i]-1];      }  }     /*Method to perform Inverse of Initial-Permutation*/  void SDES::InvIP(char *input)  {      int InvIPArray[8]={4,1,3,5,7,2,8,6};      int i;      InvIPOutput[8]='\0';      for (i=0;i<8;i++)      {          InvIPOutput[i]=input[InvIPArray[i]-1];      }  }     /*Method to perform SDES-Encryption on 8-bit 'input'*/  void SDES::DES_Encryption(unsigned char input)  {      char LIP[5],RIP[5],L1[5],R1[5];      int i;         INPUT=input;      conv_to_bits(INPUT);  //Converts the input to bit-string      IP(INPUT_BIT);        //Initial-Permutation         //gotoxy(1,1);      printf("\nEncrpyting.........");         /*Dividing the output of IP into 2 parts*/      for (i=0;i<4;i++)      {          LIP[i]=IPOutput[i];          RIP[i]=IPOutput[i+4];      }      LIP[4]='\0';      RIP[4]='\0';         /*Sending the above divided parts to Function_F and  sub-key K1*/      Function_F(LIP,RIP,1);         /*Dividing the output of the Function_F into 2 parts*/      for (i=0;i<4;i++)      {          L1[i]=F1Output[i];          R1[i]=F1Output[4+i];      }      L1[4]='\0';      R1[4]='\0';         /*This time the string-parameters swaped and uses sub-key K2*/      Function_F(R1,L1,2);         /*Performing the Inverse IP on the output of the Funtion_F*/      InvIP(F1Output); //The output of the function will give us      //Cipher-string         /*Cipher string is converted back to unsigned char and stored        in private-variable OUTPUT of this class*/      GetChar();  }        /*Decryption is just inverse of Encryption    Here IP, InvIP, E/P, SBOX1 and SBOX2 are same    But Function_F first operats on sub-key K2 and    then on sub-key K1*/  void SDES::DES_Decryption(unsigned char input)  {      char LIP[5],RIP[5],L1[5],R1[5];      int i;         INPUT=input;      conv_to_bits(INPUT);      IP(INPUT_BIT);        //Initial-Permutation         //gotoxy(1,1);      printf("\nDecrpyting.........");         for (i=0;i<4;i++)      {          LIP[i]=IPOutput[i];          RIP[i]=IPOutput[i+4];      }      LIP[4]='\0';      RIP[4]='\0';         Function_F(LIP,RIP,2);         for (i=0;i<4;i++)      {          L1[i]=F1Output[i];          R1[i]=F1Output[4+i];      }      L1[4]='\0';      R1[4]='\0';         Function_F(R1,L1,1);      InvIP(F1Output);      GetChar();  }     void SDES::Function_F(char *linput,char *rinput,int key)  {      int E_P[8]={4,1,2,3,2,3,4,1}; //E/P Operation-Array      int P4[4]={2,4,3,1};          //P4 Operation-Array      int i;      char E_POutput[9],*EXOR_Output,*LEXOR,*REXOR;      char *SBOX0_Output,*SBOX1_Output;      char SBOX_Output[5];      char P4_Output[5];      char fk_Output[5];      char Main_Output[9];         /*E/P Operaion is performed here*/      for (i=0;i<8;i++)      {          E_POutput[i]=rinput[E_P[i]-1];      }      E_POutput[8]='\0';         /*Bitwise-EXOR is done on E/P Output and sub-key(K1/K2)*/      EXOR_Output=EX_OR(E_POutput,key);         /*Divide the output of Exor in 2 parts*/      LEXOR=new char[strlen(EXOR_Output)/2+1];      REXOR=new char[strlen(EXOR_Output)/2+1];         for (i=0;i<strlen(EXOR_Output)/2;i++)      {          LEXOR[i]=EXOR_Output[i];          REXOR[i]=EXOR_Output[i+4];      }      LEXOR[4]=REXOR[4]='\0';            /*Peforming SBOX0 Operation on left 4 bits*/      SBOX0_Output=SBOX0(LEXOR);         /*Peforming SBOX1 Operation on right 4 bits*/      SBOX1_Output=SBOX1(REXOR);         /*Combining the 2-bits output of both SBOXES in one string*/      for (i=0;i<2;i++)      {          SBOX_Output[i]=SBOX0_Output[i];          SBOX_Output[i+2]=SBOX1_Output[i];      }      SBOX_Output[4]='\0';         /*Performing the P4 operation on SBOX output*/      for (i=0;i<4;i++)      {          P4_Output[i]=SBOX_Output[P4[i]-1];      }      P4_Output[4]='\0';         /*Performing the EXOR operation on 4-bits P4-output        and 4-bits Leftinput of Funtion_F*/      for (i=0;i<4;i++)      {          if (P4_Output[i]==linput[i])              fk_Output[i]='0';          else              fk_Output[i]='1';      }      fk_Output[4]='\0';         /*Cancating the 4-bits output of above EXOR-operation        and 4-bits Right-input of Function_F*/      for (i=0;i<4;i++)      {          Main_Output[i]=fk_Output[i];          Main_Output[i+4]=rinput[i];      }      Main_Output[8]='\0';      /*Assigning this Cucaneted string to Private variable 'F1Output'*/      strcpy(F1Output,Main_Output);  }     /*This method EXORS the output ofE/P and sub-keys    depending on the parameter k.    k=1:subkey K1  k=2:subkey K2*/  char *SDES::EX_OR(char *ep,int k)  {      char *output,*key;      int i,klen;         output=new char[strlen(ep)+1];      key=new char[strlen(K1)+1];      if (k==1)      {          strcpy(key,K1);      } else      {          if (k==2)          {              strcpy(key,K2);          } else          {              printf("\n\nWrong Choice in the key parameter(1/2)");              getch();              exit(1);          }      }      klen=strlen(K1);      if (strlen(ep)!=klen)      {          printf("\ninput=%d is not equal to K=%d",strlen(ep),klen);          printf("\n\nError in the Output of E/P (Length)..Press any key");          getch();          exit(1);      }      for (i=0;i<strlen(ep);i++)      {          if (ep[i]==key[i])              output[i]='0';          else              output[i]='1';      }      output[strlen(ep)]='\0';      return(output);  }     /*SBOX0 Operation is defined here*/  char *SDES::SBOX0(char *l)  {      int S0[4][4]={1,0,3,2,  //S0 Matrix          3,2,1,0,          0,2,1,3,          3,1,3,2      };         char *bits[]={"00","01","10","11"};      char lrow[3],lcol[3];      char *SO;      int i,lr,lc,b;         SO=new char[3];         lrow[0]=l[0];      lrow[1]=l[3];      lcol[0]=l[1];      lcol[1]=l[2];         lrow[2]='\0';      lcol[2]='\0';            for (i=0;i<4;i++)      {          if (strcmp(lrow,bits[i])==0)              lr=i;          if (strcmp(lcol,bits[i])==0)              lc=i;      }      b=S0[lr][lc];      for (i=0;i<3;i++)          SO[i]=bits[b][i];      SO[3]='\0';      return(SO);  }  /*SBOX1 Operation is defined here*/  char *SDES::SBOX1(char *l)  {      int S0[4][4]={0,1,2,3,   //S1 Matrix          2,0,1,3,          3,0,1,0,          2,1,0,3      };         char *bits[]={"00","01","10","11"};      char lrow[3],lcol[3];      char *SO;      int i,lr,lc,b;         SO=new char[3];         lrow[0]=l[0];      lrow[1]=l[3];      lcol[0]=l[1];      lcol[1]=l[2];         lrow[2]='\0';      lcol[2]='\0';            for (i=0;i<4;i++)      {          if (strcmp(lrow,bits[i])==0)              lr=i;          if (strcmp(lcol,bits[i])==0)              lc=i;      }      b=S0[lr][lc];      for (i=0;i<3;i++)          SO[i]=bits[b][i];         SO[3]='\0';      return(SO);  }     /*Method to get back unsigned char from bit-string*/  void SDES::GetChar()  {      int i,j,in;      unsigned char ch=0;      char *bs;      bs=new char[9];      bs=InvIPOutput;      if (strlen(bs)>8)      {          printf("\nWRONG LENGTH STRING");          exit(0);      }      for (i=0;i<8;i++)      {          if (bs[i]=='1')          {              in=1;              for (j=1;j<8-i;j++)              {                  in=in*2;              }              ch=ch+in;          }      }      OUTPUT=ch;  }     /*Destructor*/  SDES::~SDES()  {  }        char *sfname,*tfname;  char *key;//="1010000010";  void main(void)  {      //clrscr();      unsigned char ch,ch1;      int i,n=10,choice;         while (1)      {          key = new char[11];          sfname = new char[20];          tfname = new char[20];          mainmenu(&choice);          fflush(stdin);          switch (choice)          {          case 1:              menuEn();              DoEnDe(choice);              break;          case 2:              menuDe();              DoEnDe(choice);              break;          case 3:              exit(0);          default:              printf("\nWrong Choice Enter again\nPress any key to return to Main Menu..");              getch();              break;          }      }  }     void mainmenu(int *c)  {      //clrscr();      printf("\nWhat do you want to do..");      printf("\n1. Encryption");      printf("\n2. Decryption");      printf("\n3. Exit");      printf("\n\nEnter the choice? ");      scanf("%d",c);  }  void menuEn()  {      //clrscr();      sfname=new char[20];      tfname=new char[20];      key=new char[11];      printf("\nEncryption Menu\n\n");      printf("\nEnter the filename to be Encrypted: ");      gets(sfname);      printf("\nEnter the Target file name: ");      gets(tfname);      printf("\nEnter the 10-bits KEY: ");      gets(key);      printf("\n\nNotedown this key, as same key is used for Decryption");      //getch();  }     void menuDe()  {      //clrscr();      sfname=new char[20];      tfname=new char[20];      key=new char[11];      printf("\nDecryption Menu\n\n");      printf("\nEnter the filename to be Decrypted: ");      gets(sfname);      printf("\nEnter the Target file name: ");      gets(tfname);      printf("\nEnter the 10-bits KEY: ");      gets(key);  }     int DoEnDe(int c)  {      SDES S(key);      int i,n;      n=10; //Number of Rounds      unsigned char ch;      FILE *fp;      FILE *ft;      fp=fopen(tfname,"w");      ft=fopen(sfname,"r");      if (fp==NULL)      {          printf("\nTarget File not opened SORRY");          getch();          fclose(fp);          return(0);      }      if (ft==NULL)      {          printf("\nSource File not opened SORRY");          getch();          fclose(ft);          return(0);      }      while (fread(&ch,1,1,ft)==1)      {          S.OUTPUT=ch;             for (i=0;i<n;i++)          {              if (c==1)                  S.DES_Encryption(S.OUTPUT);              if (c==2)                  S.DES_Decryption(S.OUTPUT);          }          fwrite(&S.OUTPUT,1,1,fp);      }      printf("\nCompleted!!!!!");      getch();      fclose(fp);      fclose(ft);      return(1);  }