C++簡單數據加密算法實現加密和解密

mx3y 9年前發布 | 2K 次閱讀 C/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=in2; } 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);

}</pre>

 本文由用戶 mx3y 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!