请,我需要有关此SDES加密和解密配方案的帮助。 [英] Please, I need help with this SDES encrypting and deencrypting scheme.

查看:91
本文介绍了请,我需要有关此SDES加密和解密配方案的帮助。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从网上获得了这个加密代码。由于我通常使用unicode,我希望将其重写为16位字符。我只是不明白变量P10 [10]和P8 [8]的值是如何得到的。它们是按照特定顺序还是随机生成的。



上述问题已得到解答。我使用了它运行良好的代码,但很快耗尽了堆,因为很多指针是动态分配的而不是释放。

我试着为它编写一个析构函数。但是没有成功。我还尝试了其他点来释放allOcated内存,但不断被编译器抛出异常。任何人都可以帮我发送所有动态分配的内存吗?








>
如何使其适用于宽字符类型?

I got this encryption code from the net. Since I generally use unicode, i wish to re-write it for 16 bit character. I just don't understand how the values of variables P10[10] and P8[8] where gotten. Do they follow a particular sequence or they are randomly generated.

The above question has been answered . I used the code it worked fine but soon exhausted the heap because a lot of pointers were dynamically allocated without being release.
I tried to write a destructor for it. but was unsuccessful.I also tried other points for releasing the allOcated memory but keep getting exception thrown by the compiler. Please can any body help me with THE RELEASING OF ALL DYNAMICALLY ALLOCATED MEMORY?




What do I do to make it work for wide char type?

#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&lt;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//How were this numbers generated
    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//How were this numbers generated
    char *P10LEFT,*pl,*pl1,*P10RIGHT,*pr,*pr1,*plpr;
    int i;
    /*P10 operation is done on main key*/
    for (i=0;i&lt;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&lt;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&lt;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&lt;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&lt;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&lt;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&lt;n;j++)&gt;
    {
        firstbit=char_ptr[0];
        for (i=0;i&lt;length-1;i++)&gt;
        {
            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&gt;=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&lt;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&lt;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&lt;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&lt;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&lt;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&lt;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&lt;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    {
        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&lt;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&lt;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&lt;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&lt;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&lt;strlen(ep);i++)&gt;
    {
        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&lt;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&lt;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&lt;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&lt;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)&gt;8)
    {
        printf("\nWRONG LENGTH STRING");
        exit(0);
    }
    for (i=0;i&lt;8;i++)
    {
        if (bs[i]=='1')
        {
            in=1;
            for (j=1;j&lt;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&lt;n;i++)&gt;
        {
            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);
}

推荐答案

Solution 1: Convert your unicode string to utf8

Solution 2: Cast your buffer to a char* and encode it as binary data no matter what it contains.



Usually you are encoding binary data and not text and characters. Note that a 16 bit widechar (wchar_t) isn’t a unicode character! That was tha case with UCS encoding but with the advent of utf-16 this is no longer true! There are around 1million characters in the unicode table and only utf-32 can represent 1 character with 1 (32bit)word used by the encoding. In utf16 the (16bit)words can store at most 2^16 characters so sometimes 2 words are used to describe 1 unicode characters (this utf16 word-pair is called a high and low surrogate pair). So it makes no sense to mess around with (wchar_t) because it isn’t unicode at all and all you can achieve with that is making an otherwise scure encryption unsecure! Instead of your original plan just encode your unicode text to whatever format (utf32, utf16, or utf8) or leave it as it is and cast the whole buffer into a byte array and encrypt that. The encryption doesn’t care what kind of data you encrypt.



PS: Using unicode and using wchar_t are two totally different things. I usually use utf-8 to store unicode strings and I’m usually using norma char pointers becuase thats much natural for the C/C++ language plus it makes porting my application much easier to unix like systems where utf8 is the native format. String-related efficiency has never been an issue in my apps because of the utf8-utf16 conversion on WinNT (since the native format of WinNT is utf16) but I can image an application where string-operations are frequent and this can could cause performance issues. In that case I would go with a string class with utf16 internal representation, but in practice this never happened to me.
Solution 1: Convert your unicode string to utf8
Solution 2: Cast your buffer to a char* and encode it as binary data no matter what it contains.

Usually you are encoding binary data and not text and characters. Note that a 16 bit widechar (wchar_t) isn't a unicode character! That was tha case with UCS encoding but with the advent of utf-16 this is no longer true! There are around 1million characters in the unicode table and only utf-32 can represent 1 character with 1 (32bit)word used by the encoding. In utf16 the (16bit)words can store at most 2^16 characters so sometimes 2 words are used to describe 1 unicode characters (this utf16 word-pair is called a high and low surrogate pair). So it makes no sense to mess around with (wchar_t) because it isn't unicode at all and all you can achieve with that is making an otherwise scure encryption unsecure! Instead of your original plan just encode your unicode text to whatever format (utf32, utf16, or utf8) or leave it as it is and cast the whole buffer into a byte array and encrypt that. The encryption doesn't care what kind of data you encrypt.

PS: Using unicode and using wchar_t are two totally different things. I usually use utf-8 to store unicode strings and I'm usually using norma char pointers becuase thats much natural for the C/C++ language plus it makes porting my application much easier to unix like systems where utf8 is the native format. String-related efficiency has never been an issue in my apps because of the utf8-utf16 conversion on WinNT (since the native format of WinNT is utf16) but I can image an application where string-operations are frequent and this can could cause performance issues. In that case I would go with a string class with utf16 internal representation, but in practice this never happened to me.


Given the 10-bit key [k1, k2, k3, k4,k5,k6,k7,k8,k9,k10]



P10:

Input: 1 2 3 4 5 6 7 8 9 10

Output: 3 5 2 7 4 10 1 9 8 6



It is a fixed permutation. It is one of the flaws of S-DES because the output is fixed/predefined.



For example, given the key 1000010110 the P10 is 0000001111



P8:

Input: 1 2 3 4 5 6 7 8 9 10

Output: 6 3 7 4 8 5 10 9



It is a fixed permutation.



You can find the full explanation on the YouTube video: Simplified DES Example
Given the 10-bit key [k1, k2, k3, k4,k5,k6,k7,k8,k9,k10]

P10:
Input: 1 2 3 4 5 6 7 8 9 10
Output: 3 5 2 7 4 10 1 9 8 6

It is a fixed permutation. It is one of the flaws of S-DES because the output is fixed/predefined.

For example, given the key 1000010110 the P10 is 0000001111

P8:
Input: 1 2 3 4 5 6 7 8 9 10
Output: 6 3 7 4 8 5 10 9

It is a fixed permutation.

You can find the full explanation on the YouTube video: Simplified DES Example


这篇关于请,我需要有关此SDES加密和解密配方案的帮助。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆