C++简单数据加密算法实现加密和解密
2018-07-20 来源:open-open
/* 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); }
标签: swap
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。
上一篇:C++清空或删除文件夹
下一篇:C++编写的页面淘汰算法LRU
最新资讯
热门推荐