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

📄 yxydes.cpp

📁 一个叫尹学渊的人写的DES的程序,注释的非常详细.适合那些对C++不是很精通的人.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        {
                szPlaintextBinary[j] = sz_Final64[IPR_Table[j]-1];
        }
        memcpy(szPlaintext,BinaryToString(szPlaintextBinary,64,false).c_str(),8); 
		//c_str(),有什么意义???
}

void yxyDES::FunctionF(char* sz_Li,char* sz_Ri,int iKey)   //f函数
{
        char sz_48R[48] = {0};
        char sz_xor48[48] = {0};
        char sz_P32[32] = {0};
        char sz_Rii[32] = {0};
        char sz_Key[48] = {0};
        memcpy(sz_Key,SubKeys[iKey],48);   //SubKeys[16][48],存放16轮的子密钥
        ExpansionR(sz_Ri,sz_48R);    //E扩展,将右32位进行扩展位48位,sz_48R存放了经过扩展后的右边
        XOR(sz_48R,sz_Key,48,sz_xor48);  //异或函数,右边扩展后和密钥异或,放入sz_xor48
        string s_Compress32 = CompressFuncS(sz_xor48);   //经过S盒压缩后的值返回
        PermutationP(s_Compress32,sz_P32);  //P置换,放入sz_P32
        XOR(sz_P32,sz_Li,32,sz_Rii);
        memcpy(sz_Li,sz_Ri,32);
        memcpy(sz_Ri,sz_Rii,32);
}

//加密和解密的IP变换
void yxyDES::InitialPermuteData(string s,char* Return_value,bool bType) 
{
        //if bType==true is encrypt,s是需要加密的64bit明文
        //else is decrypt,s则是需要解密的64bit密文
        if(bType)
        {
                char sz_64data[64] = {0};
                int iTmpBit[64] = {0};
                for(int i=0;i<64;i++)
                {
                        iTmpBit[i] = (s[i>>3]>>(i&7)) & 1;  //难啊!!!
                        //a = 0x61 = 0110,0001
                        //after this , a is 1000,0110

                }
                //let me convert it to right
                for(int j=0;j<8;j++)
                        for(int k=0;k<8;k++)
                                sz_64data[8*j+k] = SingleBinaryToChar(iTmpBit[8*(j+1)-(k+1)]);
                //加密IP
                char sz_IPData[64] = {0};
                for(int k=0;k<64;k++)
                {
                        sz_IPData[k] = sz_64data[IP_Table[k]-1];
                }
                memcpy(Return_value,sz_IPData,64);
        }
        else
        {
                string sz_64data;  
                for(unsigned int ui=0;ui<s.length();ui++)     
				//s是需要解密的字符串,为什么不把length直接写成16???               
				{
                        char ch = s[ui];
                        sz_64data += HexCharToBinary(tolower(ch));  //将密文16进制转换成二进制
                }
				//解密IP
                char sz_IPData[64] = {0};
                for(int i=0;i<64;i++)
                {
                        sz_IPData[i] = sz_64data[IP_Table[i]-1];   
				//把sz_64date中经过IP置换的元素放到sz_IPdata中
                }
                memcpy(Return_value,sz_IPData,64);
        }

}

void yxyDES::ExpansionR(char* sz,char* Return_value)  //将右32位进行扩展位48位
{
        char sz_48ER[48] = {0};
        for(int i=0;i<48;i++)
        {
                sz_48ER[i] = sz[E_Table[i]-1];  //sz为没有扩展的右边
        }
        memcpy(Return_value,sz_48ER,48);
}

void yxyDES::XOR(char* sz_P1,char* sz_P2,int len,char* Return_value)  
//异或函数,右边和密钥相异或
//sz_p1:扩展后的右边; sz_p2:每一轮的密钥; len:48; return_value:保存异或后的值
{
        char sz_Buffer[256] = {0};
        for(int i=0;i<len;i++)
        {
                sz_Buffer[i] = SingleBinaryToChar(SingleCharToBinary(sz_P1[i]) ^ SingleCharToBinary(sz_P2[i]));
        }
        memcpy(Return_value,sz_Buffer,len);
}

string yxyDES::CompressFuncS(char* sz_48)  //S盒压缩数据,sz_48,实参sz_xor48
{
        char sTmp[8][6] = {0};
        string sz_32 = "";     
        for(int i=0;i<8;i++)
        {
                memcpy(sTmp[i],sz_48 + 6 * i,6);  //将48bit分为8组,sTmp[8][6]
                int iX = SingleCharToBinary(sTmp[i][0]) * 2 + SingleCharToBinary(sTmp[i][5]);
                int iY = 0;
                for(int j=1;j<5;j++)
                {
                        iY += SingleCharToBinary(sTmp[i][j]) * pow(2.0,4-j);  //pow(a,b),即a^b
                }
                sz_32 += HexIntToBinary(S_Box[i][iX][iY]); 
				//const static int S_Box[8][4][16]
        }
        return sz_32;
}

void yxyDES::PermutationP(string s,char* Return_value)   //P置换,S为经过S盒后的32bit
{
        char sz_32bits[32] = {0};
        for(int i=0;i<32;i++)
        {
                sz_32bits[i] = s[P_Table[i]-1];
        }
        memcpy(Return_value,sz_32bits,32);
}

int yxyDES::SingleCharToBinary(char ch)  //单个char '0'或'1' 到int 0或1的变换
{
        if(ch == '1')
                return 1;
        else
                return 0;
}

char yxyDES::SingleBinaryToChar(int i)  //将int类型的0或1转换为char类型的0或1
{
        if(i == 1)
                return '1';
        else
                return '0';
}
void yxyDES::SetCiphertext(char* value)
{
        memcpy(szCiphertext,value,16);
}
char* yxyDES::GetCiphertext()
{
        return szCiphertext;
}

void yxyDES::SetPlaintext(char* value)
{
        memcpy(szPlaintext,value,8);
}
char* yxyDES::GetPlaintext()
{
        return szPlaintext;
}
//any length
void yxyDES::EncryptAnyLength(string szSource)  //szSource是在main中输入的明文
{
        int iLength = szSource.length();    //用函数length()求输入明文的长度
        //if the length is 8 , call EncyptData
        if(iLength == 8)
        {
                EncryptData(szSource);
                memcpy(szFCiphertextAnyLength,szCiphertext,16);  //将加密好的密文放到szFCphertextAnyLength中
                //set the last char to '\0'
                szFCiphertextAnyLength[16] = '\0';
        }
        //else if the length less than 8
        //call FillToEightBits
        else if(iLength < 8)
        {
                szSource = FillToEightBits(szSource);  //不足8字节用$补足
                EncryptData(szSource);
                memcpy(szFCiphertextAnyLength,szCiphertext,16);
                //set the last char to '\0'
                szFCiphertextAnyLength[16] = '\0';
        }
        //else if then lenth bigger than 8
        //divide the string to multi-parts
        else if(iLength > 8)
        {
                int iParts = ceil(iLength/8.0);  //例:7.6则取7
                int iResidue = iLength % 8;  //明文除以8以后剩余的字节
                string szLast8Bits;
                //encrypt the data 8 by 8 except the last part
                for(int i=0;i<iParts-1;i++)
                {
                        string szTmp = szSource.substr(i*8,8);
                        EncryptData(szTmp);
                        //after call EncryptData
                        //cpoy the temp result to szFCiphertextAnyLength
                        memcpy(szFCiphertextAnyLength + 16*i,szCiphertext,16);
                }
                //now , the last part
                if(iResidue != 0) //can't be divided exactly by 8
                {
                        szLast8Bits = szSource.substr((iParts-1)*8,iResidue);
                        szLast8Bits = FillToEightBits(szLast8Bits);
                }
                else //be divided exactly by 8
                {
                        szLast8Bits = szSource.substr((iParts-1)*8,8);
                }
                //encrypt the last part
                EncryptData(szLast8Bits);
                memcpy(szFCiphertextAnyLength + 16*(iParts - 1),szCiphertext,16);
                //set the last char to '\0'
                szFCiphertextAnyLength[(iParts)*16] = '\0';
        }
}

//fill the data to 8 bits
string yxyDES::FillToEightBits(string sz)
{
        //length less than 8 , add zero(s) to tail
        switch(sz.length())
        {
                case 7:
                        sz += "$";
                        break;
                case 6:
                        sz += "$$";
                        break;
                case 5:
                        sz += "$$$";
                        break;
                case 4:
                        sz += "$$$$";
                        break;
                case 3:
                        sz += "$$$$$";
                        break;
                case 2:
                        sz += "$$$$$$";
                        break;
                case 1:
                        sz += "$$$$$$$";
                        break;
                default:
                        break;
        }
        return sz;
}

char* yxyDES::GetCiphertextAnyLength()
{
        return szFCiphertextAnyLength;
}

void yxyDES::DecryptAnyLength(string szSource)  //解密任意长度十六进制字符串
{
        int iLength = szSource.length();  //得到密文的长度   
    	int iRealLengthOfPlaintext = 0;
        //if the length is 16 , call DecyptData
        if(iLength == 16)
        {
                DecryptData(szSource);
                memcpy(szFPlaintextAnyLength,szPlaintext,8);
				iRealLengthOfPlaintext = 8;
        }
        //it's not impossible the length less than 16
        else if(iLength < 16)
        {
                sprintf(szFPlaintextAnyLength,"Please enter your correct cipertext!");
        }
        //else if then lenth bigger than 16
        //divide the string to multi-parts
        else if(iLength > 16)
        {
                int iParts = ceil(iLength/16.0);
                int iResidue = iLength % 16;
                //if the data can't be divided exactly by 16
                //it's meaning the data is a wrong !
                if(iResidue != 0)
                {
                        sprintf(szFPlaintextAnyLength,"Please enter your correct cipertext!");
                        return;
                }
				iRealLengthOfPlaintext = iParts * 8;
                //Decrypt the data 16 by 16
                for(int i=0;i<iParts;i++)  //把密问16个字符串一组分开解密
                {
                        string szTmp = szSource.substr(i*16,16);  
                        DecryptData(szTmp);
                        //after call DecryptData
                        //cpoy the temp result to szFPlaintextAnyLength
                        memcpy(szFPlaintextAnyLength + 8*i,szPlaintext,8);
                }
        }
        //find and clear the mark
        //which is add by program when ciphertext is less than 8
        CleanPlaintextMark(iRealLengthOfPlaintext);
}

char* yxyDES::GetPlaintextAnyLength()
{
        return szFPlaintextAnyLength;
}

void yxyDES::CleanPlaintextMark(int iPlaintextLength)  
     //将不足8位而补齐的明文处理还原,处理DecryptAnyLength得出的iRealLengthOfPlaintext
{
		if(iPlaintextLength > 0 && iPlaintextLength < 8192)
		{
			szFPlaintextAnyLength[iPlaintextLength] = '\0';
		}
        char szLast7Chars[7] = {0};
        memcpy(szLast7Chars,szFPlaintextAnyLength + iPlaintextLength - 7,7); 
		//将解密出来的明文的最后7个字节放入szLast7Chars(解密出来的明文最少8位,且位数是8的倍数)
        for(int i=0;i<7;i++)
        {
                char* pDest = strrchr(szLast7Chars,'$');
                if(pDest == NULL)
                {
                        break;
                }
                else
                {
                        int iPos = (int)(pDest - szLast7Chars + 1);
                        if(iPos != 7 - i)
                        {
                                break;
                        }
                        else
                        {
                                szLast7Chars[6-i]='\0';
                                continue;
                        }
                }
        }
        memcpy(szFPlaintextAnyLength + iPlaintextLength - 7,szLast7Chars,7);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -