飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 6666|回复: 6

[C/C++] 标准DES算法 -- 飘云测试通过

[复制链接]
  • TA的每日心情
    开心
    2024-12-1 11:04
  • 签到天数: 12 天

    [LV.3]偶尔看看II

    发表于 2014-2-5 00:47:57 | 显示全部楼层 |阅读模式

    1. #ifndef  _DES_ENCRYPT_DECRYPT
    2. #define  _DES_ENCRYPT_DECRYPT

    3. #define BYTE   unsigned char
    4. #define LPBYTE   BYTE*
    5. #define LPCBYTE   const BYTE*
    6. #define BOOL   int

    7. class DES
    8. {
    9. public:
    10.         BOOL CDesEnter(LPCBYTE in, LPBYTE out, int datalen, const BYTE key[8], BOOL type);
    11.         BOOL CDesMac(LPCBYTE mac_data, LPBYTE mac_code, int datalen, const BYTE key[8]);
    12. private:
    13.         void XOR(const BYTE in1[8], const BYTE in2[8], BYTE out[8]);
    14.         LPBYTE Bin2ASCII(const BYTE byte[64], BYTE bit[8]);
    15.         LPBYTE ASCII2Bin(const BYTE bit[8], BYTE byte[64]);
    16.         void GenSubKey(const BYTE oldkey[8], BYTE newkey[16][8]);
    17.         void endes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8]);
    18.         void undes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8]);
    19.         void SReplace(BYTE s_bit[8]);
    20. };

    21. #endif
    复制代码

    1. #include "DES.h"

    2. /*
    3. *   CDesEnter 函数说明:
    4. *     des加密/解密入口
    5. *   返回:
    6. *     1则成功,0失败
    7. *   参数:
    8. *     in 需要加密或解密的数据  
    9. *         注意:in缓冲区的大小必须和datalen相同.
    10. *     out 加密后或解密后输出。
    11. *         注意:out缓冲区大小必须是8的倍数而且比datalen大或者相等。
    12. *         如datalen=7,out缓冲区的大小应该是8,datalen=8,out缓冲区的大小应该是8,
    13. *         datalen=9,out缓冲区的大小应该是16,依此类推。
    14. *     datalen 数据长度(字节)。  
    15. *         注意:datalen 必须是8的倍数。
    16. *     key 8个字节的加密或解密的密码。
    17. *     type 是对数据进行加密还是解密
    18. *         0 表示加密 1 表示解密
    19. */
    20. BOOL DES::CDesEnter(LPCBYTE in, LPBYTE out, int datalen, const BYTE key[8], BOOL type)
    21. {
    22.         //判断输入参数是否正确,失败的情况为:
    23.         //!in: in指针(输入缓冲)无效
    24.         //!out: out指针(输出缓冲)无效
    25.         //datalen<1: 数据长度不正确
    26.         //!key: 加/解密密码无效
    27.         //type && ((datalen % 8) !=0:选择解密方式但是输入密文不为8的倍数
    28.         if((!in) || (!out) || (datalen<1) || (!key) || (type && ((datalen % 8) !=0)))
    29.                 return false;
    30.         
    31.         
    32.         if(type==0) //选择的模式是加密
    33.         {
    34.                 // 用于存储待加密字串最后的若干字节
    35.                 // DES算法是以8个字节为单位进行加密,如果待加密字串以8为单位分段加密时,最后一段不足
    36.                 //8字节,则在后面补0,使其最后一段的长度为8字节
    37.                 // te8bit是作为存储待加密字串最后一段(不足8字节)的变量
    38.                 BYTE te8bit[8]={0,0,0,0,0,0,0,0};
    39.                
    40.                 // 这是待加密字串的调整长度
    41.                 // 如果原始长度是8的整数倍,则调整长度的值和原来的长度一样
    42.                 // 如果原始长度不是8的整数倍,则调整长度的值是能被8整除且不大于原来长度的最大整数。
    43.                 //也就是不需要补齐的块的总长度。
    44.                 int te_fixlen = datalen - (datalen % 8);
    45.                
    46.                 // 将待加密密文以8为单位分段,把最后长度不足8的一段存储到te8bit中。
    47.                 for(int i = 0; i < (datalen % 8); i++)
    48.                         te8bit[i] = in[te_fixlen + i];
    49.                
    50.                 // 将待加密字串分以8字节为单位分段加密
    51.                 for(i = 0; i < te_fixlen; i += 8)
    52.                         endes(in + i, key, out + i);
    53.                
    54.                 // 如果待加密字串不是8的整数倍,则将最后一段补齐(补0)后加密
    55.                 if(datalen % 8 != 0)
    56.                         endes(te8bit, key, out + datalen / 8 * 8);
    57.         }
    58.         else   //选择的模式是解密
    59.         {
    60.                 // 将密文以8字节为单位分段解密
    61.                 for(int i = 0; i < datalen; i += 8)
    62.                         undes(in + i, key, out + i);
    63.         }
    64.         return true;
    65. }

    66. /*
    67. *   CDesMAC 函数说明:
    68. *     DESMAC 数据验校
    69. *   返回:
    70. *     1则成功,0失败
    71. *   参数:
    72. *     mac_data MAC验校数据
    73. *         注意:Mac_data缓冲区的大小(16字节以上)必须和datalen相同,而且应是8的倍数。
    74. *     out_mac MAC验校输出(8字节)
    75. *     dadalen 数据长度(字节)。  
    76. *         注意:datalen 必须是16以上而且是8的倍数。
    77. *     key 8个字节的验校密码。      
    78. */
    79. BOOL DES::CDesMac(LPCBYTE mac_data, LPBYTE mac_code, int datalen, const BYTE key[8])
    80. {
    81.         //判断输入参数是否正确,失败的情况为:
    82.         //!mac_data: mac_data指针(输入缓冲)无效
    83.         //!mac_code: mac_code指针(输出缓冲)无效
    84.         //datalen<16: 数据长度不正确
    85.         //datalen % 8 != 0: 数据长度不为8的整数倍
    86.         //!key:密码不符合要求
    87.         if((!mac_data) || (!mac_code) || (datalen < 16) || (datalen % 8 != 0) || (!key))
    88.                 return false;
    89.         endes(mac_data, key, mac_code);
    90.         for(int i = 8; i < datalen; i += 8)
    91.         {
    92.                 XOR(mac_code, mac_data + i, mac_code);
    93.                 endes(mac_code, key, mac_code);
    94.         }
    95.         return true;
    96. }

    97. /*
    98. *   XOR 函数说明:
    99. *     将输入的两个8字节字符串异或
    100. *   返回:
    101. *     无
    102. *   参数:
    103. *     const BYTE in1[8] 输入字符串1
    104. *     const BYTE in2[8] 输入字符串2
    105. *     BYTE out[8] 输出的结果字符串      
    106. */
    107. void DES::XOR(const BYTE in1[8], const BYTE in2[8], BYTE out[8])
    108. {
    109.         for(int i = 0; i < 8; i++)
    110.                 out[i] = in1[i] ^ in2[i];  
    111. }

    112. /*
    113. *   Bin2ASCII 函数说明:
    114. *     将64字节的01字符串转换成对应的8个字节
    115. *   返回:
    116. *     转换后结果的指针
    117. *   参数:
    118. *     const BYTE byte[64] 输入字符串
    119. *     BYTE bit[8] 输出的转换结果      
    120. */
    121. LPBYTE DES::Bin2ASCII(const BYTE byte[64], BYTE bit[8])
    122. {
    123.         for(int i = 0; i < 8; i++)
    124.         {
    125.                 bit[i] = byte[i * 8] * 128 + byte[i * 8 + 1] * 64 +  
    126.                         byte[i * 8 + 2] * 32 + byte[i * 8 + 3] * 16 +  
    127.                         byte[i * 8 + 4] * 8 + byte[i * 8 + 5] * 4 +  
    128.                         byte[i * 8 + 6] * 2 + byte[i * 8 + 7];  
    129.         }
    130.         return bit;
    131. }

    132. /*
    133. *   ASCII2Bin 函数说明:
    134. *     将8个字节输入转换成对应的64字节的01字符串
    135. *   返回:
    136. *     转换后结果的指针
    137. *   参数:
    138. *     const BYTE bit[8] 输入字符串
    139. *     BYTE byte[64] 输出的转换结果      
    140. */
    141. LPBYTE DES::ASCII2Bin(const BYTE bit[8], BYTE byte[64])
    142. {
    143.         for(int i=0; i < 8; i++)
    144.                 for(int j = 0; j < 8; j++)
    145.                         byte[i * 8 + j] = ( bit[i] >> (7 - j) ) & 0x01;
    146.                 return byte;
    147. }

    148. /*
    149. *   GenSubKey 函数说明:
    150. *     由输入的密钥得到16个子密钥
    151. *   返回:
    152. *     无
    153. *   参数:
    154. *     const BYTE oldkey[8] 输入密钥
    155. *     BYTE newkey[16][8] 输出的子密钥      
    156. */
    157. void DES::GenSubKey(const BYTE oldkey[8], BYTE newkey[16][8])
    158. {
    159.         int i, k, rol = 0;
    160.         
    161.         //缩小换位表1
    162.         int pc_1[56] = {57,49,41,33,25,17,9,
    163.                 1,58,50,42,34,26,18,
    164.                 10,2,59,51,43,35,27,
    165.                 19,11,3,60,52,44,36,
    166.                 63,55,47,39,31,23,15,
    167.                 7,62,54,46,38,30,22,
    168.                 14,6,61,53,45,37,29,
    169.                 21,13,5,28,20,12,4};
    170.         //缩小换位表2
    171.         int pc_2[48] = {14,17,11,24,1,5,
    172.                 3,28,15,6,21,10,
    173.                 23,19,12,4,26,8,
    174.                 16,7,27,20,13,2,
    175.                 41,52,31,37,47,55,
    176.                 30,40,51,45,33,48,
    177.                 44,49,39,56,34,53,
    178.                 46,42,50,36,29,32};
    179.         //16次循环左移对应的左移位数
    180.         int ccmovebit[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
    181.         
    182.         BYTE oldkey_byte[64];
    183.         BYTE oldkey_byte1[64];
    184.         BYTE oldkey_byte2[64];
    185.         BYTE oldkey_c[56];
    186.         BYTE oldkey_d[56];
    187.         BYTE newkey_byte[16][64];
    188.         
    189.         ASCII2Bin(oldkey, oldkey_byte);
    190.         
    191.         //位变换
    192.         for(i = 0; i < 56; i++)
    193.                 oldkey_byte1[i] = oldkey_byte[pc_1[i] - 1];
    194.         //分为左右两部分,复制一遍以便于循环左移
    195.         for(i = 0; i < 28; i++)
    196.                 oldkey_c[i] = oldkey_byte1[i], oldkey_c[i + 28] = oldkey_byte1[i],
    197.                 oldkey_d[i] = oldkey_byte1[i + 28], oldkey_d[i + 28] = oldkey_byte1[i + 28];
    198.         
    199.         //分别生成16个子密钥
    200.         for(i = 0; i < 16; i++)
    201.         {
    202.                 //循环左移
    203.                 rol += ccmovebit[i];
    204.                 //合并左移后的结果
    205.                 for(k = 0; k < 28; k++)  
    206.                         oldkey_byte2[k] = oldkey_c[k + rol], oldkey_byte2[k + 28] = oldkey_d[k + rol];
    207.                 //位变换
    208.                 for(k = 0; k < 48; k++)
    209.                         newkey_byte[i][k] = oldkey_byte2[pc_2[k] - 1];
    210.                
    211.         }
    212.         //生成最终结果
    213.         for(i = 0; i < 16; i++)
    214.                 Bin2ASCII(newkey_byte[i], newkey[i]);
    215. }

    216. /*
    217. *   endes 函数说明:
    218. *     DES加密
    219. *   返回:
    220. *     无
    221. *   参数:
    222. *     const BYTE m_bit[8] 输入的原文
    223. *     const BYTE k_bit[8] 输入的密钥
    224. *     BYTE e_bit[8] 输出的密文
    225. */
    226. void DES::endes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8])
    227. {
    228.         //换位表IP
    229.         int ip[64] = {
    230.         58,50,42,34,26,18,10,2,
    231.                         60,52,44,36,28,20,12,4,
    232.                         62,54,46,38,30,22,14,6,
    233.                         64,56,48,40,32,24,16,8,
    234.                         57,49,41,33,25,17,9,1,
    235.                         59,51,43,35,27,19,11,3,
    236.                         61,53,45,37,29,21,13,5,
    237.                         63,55,47,39,31,23,15,7
    238.         };
    239.         //换位表IP_1
    240.         int ip_1[64] = {
    241.         40,8,48,16,56,24,64,32,
    242.                         39,7,47,15,55,23,63,31,
    243.                         38,6,46,14,54,22,62,30,
    244.                         37,5,45,13,53,21,61,29,
    245.                         36,4,44,12,52,20,60,28,
    246.                         35,3,43,11,51,19,59,27,
    247.                         34,2,42,10,50,18,58,26,
    248.                         33,1,41,9,49,17,57,25
    249.         };
    250.         //放大换位表
    251.         int e[48] = {
    252.         32,1, 2, 3, 4, 5,
    253.                         4, 5, 6, 7, 8, 9,
    254.                         8, 9, 10,11,12,13,
    255.                         12,13,14,15,16,17,
    256.                         16,17,18,19,20,21,
    257.                         20,21,22,23,24,25,
    258.                         24,25,26,27,28,29,
    259.                         28,29,30,31,32,1
    260.         };
    261.         BYTE m_bit1[8] = {0};
    262.         BYTE m_byte[64] = {0};
    263.         BYTE m_byte1[64] = {0};
    264.         BYTE key_n[16][8] = {0};
    265.         BYTE l_bit[17][8] = {0};
    266.         BYTE r_bit[17][8] = {0};
    267.         BYTE e_byte[64] = {0};
    268.         BYTE e_byte1[64] = {0};
    269.         BYTE r_byte[64] = {0};
    270.         BYTE r_byte1[64] = {0};
    271.         int i, j;
    272.         
    273.         //根据密钥生成16个子密钥
    274.         GenSubKey(k_bit, key_n);
    275.         //将待加密字串变换成01串
    276.         ASCII2Bin(m_bit, m_byte);
    277.         //按照ip表对待加密字串进行位变换
    278.         for(i = 0; i < 64; i++)
    279.                 m_byte1[i] = m_byte[ip[i] - 1];
    280.         //位变换后的待加密字串
    281.         Bin2ASCII(m_byte1, m_bit1);
    282.         //将位变换后的待加密字串分成两组,分别为前4字节L和后4字节R,作为迭代的基础(第0次迭代)
    283.         for(i = 0; i < 4; i++)
    284.                 l_bit[0][i] = m_bit1[i], r_bit[0][i] = m_bit1[i + 4];
    285.         
    286.         //16次迭代运算
    287.         for(i = 1; i <= 16; i++)
    288.         {
    289.                 //R的上一次的迭代结果作为L的当前次迭代结果
    290.                 for(j = 0; j < 4; j++)
    291.                         l_bit[i][j] = r_bit[i-1][j];
    292.                
    293.                 ASCII2Bin(r_bit[i-1], r_byte);
    294.                 //将R的上一次迭代结果按E表进行位扩展得到48位中间结果
    295.                 for(j = 0; j < 48; j++)
    296.                         r_byte1[j] = r_byte[e[j] - 1];
    297.                 Bin2ASCII(r_byte1, r_bit[i-1]);
    298.                
    299.                 //与第I-1个子密钥进行异或运算
    300.                 for(j = 0; j < 6; j++)
    301.                         r_bit[i-1][j] = r_bit[i-1][j] ^ key_n[i-1][j];
    302.                
    303.                 //进行S选择,得到32位中间结果
    304.                 SReplace(r_bit[i - 1]);
    305.                
    306.                 //结果与L的上次迭代结果异或得到R的此次迭代结果
    307.                 for(j = 0; j < 4; j++)
    308.                 {
    309.                         r_bit[i][j] = l_bit[i-1][j] ^ r_bit[i-1][j];
    310.                 }
    311.         }
    312.         //组合最终迭代结果
    313.         for(i = 0; i < 4; i++)
    314.                 e_bit[i] = r_bit[16][i], e_bit[i + 4] = l_bit[16][i];
    315.         
    316.         ASCII2Bin(e_bit, e_byte);
    317.         //按照表IP-1进行位变换
    318.         for(i = 0; i < 64; i++)
    319.                 e_byte1[i] = e_byte[ip_1[i] - 1];
    320.         //得到最后的加密结果
    321.         Bin2ASCII(e_byte1, e_bit);
    322. }

    323. /*
    324. *   undes 函数说明:
    325. *     DES解密,与加密步骤完全相同,只是迭代顺序是从16到1
    326. *   返回:
    327. *     无
    328. *   参数:
    329. *     const BYTE m_bit[8] 输入的密文
    330. *     const BYTE k_bit[8] 输入的密钥
    331. *     BYTE e_bit[8] 输出解密后的原文
    332. */
    333. void DES::undes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8])
    334. {
    335.         //换位表IP
    336.         int ip[64] = {
    337.         58,50,42,34,26,18,10,2,
    338.                 60,52,44,36,28,20,12,4,
    339.                 62,54,46,38,30,22,14,6,
    340.                 64,56,48,40,32,24,16,8,
    341.                 57,49,41,33,25,17,9,1,
    342.                 59,51,43,35,27,19,11,3,
    343.                 61,53,45,37,29,21,13,5,
    344.                 63,55,47,39,31,23,15,7
    345.         };
    346.         //换位表IP_1
    347.         int ip_1[64] = {
    348.         40,8,48,16,56,24,64,32,
    349.                 39,7,47,15,55,23,63,31,
    350.                 38,6,46,14,54,22,62,30,
    351.                 37,5,45,13,53,21,61,29,
    352.                 36,4,44,12,52,20,60,28,
    353.                 35,3,43,11,51,19,59,27,
    354.                 34,2,42,10,50,18,58,26,
    355.                 33,1,41,9,49,17,57,25
    356.         };
    357.         //放大换位表
    358.         int e[48] = {
    359.         32,1, 2, 3, 4, 5,
    360.                 4, 5, 6, 7, 8, 9,
    361.                 8, 9, 10,11,12,13,
    362.                 12,13,14,15,16,17,
    363.                 16,17,18,19,20,21,
    364.                 20,21,22,23,24,25,
    365.                 24,25,26,27,28,29,
    366.                 28,29,30,31,32,1
    367.         };
    368.         BYTE m_bit1[8] = {0};
    369.         BYTE m_byte[64] = {0};
    370.         BYTE m_byte1[64] = {0};
    371.         BYTE key_n[16][8] = {0};
    372.         BYTE l_bit[17][8] = {0};
    373.         BYTE r_bit[17][8] = {0};
    374.         BYTE e_byte[64] = {0};
    375.         BYTE e_byte1[64] = {0};
    376.         BYTE l_byte[64] = {0};
    377.         BYTE l_byte1[64] = {0};
    378.         int i = 0, j = 0;
    379.         
    380.         //根据密钥生成16个子密钥
    381.         GenSubKey(k_bit, key_n);
    382.         //将待加密字串变换成01串
    383.         ASCII2Bin(m_bit, m_byte);
    384.         //按照ip表对待加密字串进行位变换
    385.         for(i = 0; i < 64; i++)
    386.                 m_byte1[i] = m_byte[ip[i] - 1];
    387.         //位变换后的待加密字串
    388.         Bin2ASCII(m_byte1, m_bit1);
    389.         //将位变换后的待加密字串分成两组,分别为前4字节R和后4字节L,作为迭代的基础(第16次迭代)
    390.         for(i = 0; i < 4; i++)
    391.                 r_bit[16][i] = m_bit1[i], l_bit[16][i] = m_bit1[i + 4];
    392.         
    393.         //16次迭代运算
    394.         for(i = 16; i > 0; i--)
    395.         {
    396.                 //L的上一次的迭代结果作为R的当前次迭代结果
    397.                 for(j = 0; j < 4; j++)
    398.                         r_bit[i-1][j] = l_bit[i][j];
    399.                
    400.                 ASCII2Bin(l_bit[i], l_byte);
    401.                 //将L的上一次迭代结果按E表进行位扩展得到48位中间结果
    402.                 for(j = 0; j < 48; j++)
    403.                         l_byte1[j] = l_byte[e[j] - 1];
    404.                 Bin2ASCII(l_byte1, l_bit[i]);
    405.                
    406.                 //与第I-1个子密钥进行异或运算
    407.                 for(j = 0; j < 6; j++)
    408.                         l_bit[i][j] = l_bit[i][j] ^ key_n[i-1][j];
    409.                
    410.                 //进行S选择,得到32位中间结果
    411.                 SReplace(l_bit[i]);
    412.                
    413.                 //结果与R的上次迭代结果异或得到L的此次迭代结果
    414.                 for(j = 0; j < 4; j++)
    415.                 {
    416.                         l_bit[i-1][j] = r_bit[i][j] ^ l_bit[i][j];
    417.                 }
    418.         }
    419.         //组合最终迭代结果
    420.         for(i = 0; i < 4; i++)
    421.                 e_bit[i] = l_bit[0][i], e_bit[i + 4] = r_bit[0][i];
    422.         
    423.         ASCII2Bin(e_bit, e_byte);
    424.         //按照表IP-1进行位变换
    425.         for(i = 0; i < 64; i++)
    426.                 e_byte1[i] = e_byte[ip_1[i] - 1];
    427.         //得到最后的结果
    428.         Bin2ASCII(e_byte1, e_bit);
    429. }

    430. /*
    431. *   SReplace 函数说明:
    432. *     S选择
    433. *   返回:
    434. *     无
    435. *   参数:
    436. *     BYTE s_bit[8] 输入暨选择后的输出
    437. */
    438. void DES::SReplace(BYTE s_bit[8])
    439. {
    440.         int p[32] = {
    441.         16,7,20,21,
    442.                 29,12,28,17,
    443.                 1,15,23,26,
    444.                 5,18,31,10,
    445.                 2,8,24,14,
    446.                 32,27,3,9,
    447.                 19,13,30,6,
    448.                 22,11,4,25
    449.         };
    450.         
    451.         BYTE s[][4][16] ={  
    452.                 {
    453.                         14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
    454.                         0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
    455.                         4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
    456.                         15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13
    457.                 },
    458.                 {
    459.                         15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
    460.                         3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
    461.                         0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
    462.                         13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9
    463.                 },
    464.                 {
    465.                         10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
    466.                         13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
    467.                         13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
    468.                         1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12
    469.                 },
    470.                 {
    471.                         7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
    472.                         13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
    473.                         10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
    474.                         3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14
    475.                 },
    476.                 {
    477.                         2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
    478.                         14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
    479.                         4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
    480.                         11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
    481.                 },
    482.                 {
    483.                         12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
    484.                         10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
    485.                         9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
    486.                         4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13
    487.                 },
    488.                 {
    489.                         4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
    490.                         13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
    491.                         1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
    492.                         6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12
    493.                 },
    494.                 {
    495.                         13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
    496.                         1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
    497.                         7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
    498.                         2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
    499.                 }
    500.         };
    501.         BYTE s_byte[64] = {0};
    502.         BYTE s_byte1[64] = {0};
    503.         BYTE row = 0, col = 0;
    504.         BYTE s_out_bit[8] = {0};
    505.         
    506.         //转成二进制字符串处理
    507.         ASCII2Bin(s_bit, s_byte);
    508.         for(int i = 0; i < 8; i++)
    509.         {
    510.                 //0、5位为row,1、2、3、4位为col,在S表中选择一个八位的数
    511.                 row = s_byte[i * 6] * 2 + s_byte[i * 6 + 5];
    512.                 col = s_byte[i * 6 + 1] * 8 + s_byte[i * 6 + 2] * 4 + s_byte[i * 6 + 3] * 2 + s_byte[i * 6 + 4];
    513.                 s_out_bit[i] = s[i][row][col];
    514.         }
    515.         //将八个选择的八位数据压缩表示
    516.         s_out_bit[0] = (s_out_bit[0] << 4) + s_out_bit[1];
    517.         s_out_bit[1] = (s_out_bit[2] << 4) + s_out_bit[3];
    518.         s_out_bit[2] = (s_out_bit[4] << 4) + s_out_bit[5];
    519.         s_out_bit[3] = (s_out_bit[6] << 4) + s_out_bit[7];
    520.         //转成二进制字符串处理
    521.         ASCII2Bin(s_out_bit, s_byte);
    522.         //换位
    523.         for(i = 0; i < 32; i++)
    524.                 s_byte1[i] = s_byte[p[i] - 1];
    525.         //生成最后结果
    526.         Bin2ASCII(s_byte1, s_bit);
    527. }

    复制代码

    test:
    1. void main()
    2. {
    3.     DES des;
    4.         int i = 0;
    5.     unsigned char szName[256]="piaoyun";
    6.     byte szSn1[8] = {0};
    7.         byte szSn2[8] = {0};
    8.     unsigned char szKey1[9]="emnehsab";
    9.         unsigned char szKey2[9]="cABlEwIR";
    10.     des.CDesEnter(szName, szSn1, 8, szKey1, 0);
    11.         des.CDesEnter(szName, szSn2, 8, szKey2, 0);

    12.         printf("注册码:\n");
    13.         for (i=0; i < sizeof(szSn1); i++)
    14.         {
    15.                 printf("%02X",szSn1[i]);        
    16.         }
    17.         for (i=0; i < sizeof(szSn2); i++)
    18.         {
    19.                 printf("%02X",szSn2[i]);        
    20.         }
    21.         printf("\n");
    22. }
    复制代码


    评分

    参与人数 1威望 +4 飘云币 +4 收起 理由
    beijingren + 4 + 4 神马都是浮云

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2022-4-8 23:42
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2014-2-23 14:21:21 来自手机 | 显示全部楼层
    飘老板,细细用程序验证了下,非常标准滴算法,只是不懂得怎么修改源码支持:明文 加密结果以及解密的待解密明文,解密结果  全部修改成输入输出全部为16进制模式,密钥能改就更好。目的:研究下非标准算猫腻是否是循环轮数减少或者box数据改动。。。。只把加密模式看了下,解密模式改成0后,为在szname输入待解密明文把密钥倒过来,得不到正确结果,应该是处理密钥subkey的代码已经做了这个事情,另外一个原因,od里加密结果字符串n多记事本识别乱码,何况cmd........老板有空能不能在算法开始处把处理输入的代码改成全部16输入输出,,,,卑职不懂编程,谢谢了
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2022-4-8 23:42
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2014-3-22 11:34:59 | 显示全部楼层
    飘云阁总理的这个C++源码这么给力,关注的人却这么少,蛋碎了,等大家遇到非标准算法就知道这个源码的优秀了,但愿总理能开源多个算法+HEX支持,这是算法分析的提高关键,对于尔等。。。。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-3-25 15:21
  • 签到天数: 487 天

    [LV.9]以坛为家II

    发表于 2014-3-22 12:52:17 | 显示全部楼层
    可惜不懂C啊 看不懂 悲催
    PYG19周年生日快乐!
  • TA的每日心情
    慵懒
    2015-8-14 00:08
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    发表于 2014-6-12 00:49:56 | 显示全部楼层
    很不错的,可惜看不懂,悲剧。。。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-12-31 11:44
  • 签到天数: 701 天

    [LV.9]以坛为家II

    发表于 2014-6-22 23:11:53 | 显示全部楼层
    学习中,谢谢
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表