• DES


     1 /*
     2 2015.4
     3 DES加解密类
     4 */
     5 #ifndef DES_H
     6 #define DES_H
     7 
     8 #include <iostream>  
     9 #include <string>
    10 #include <bitset>    
    11 using namespace std;
    12 
    13 class DES
    14 {
    15 public:
    16     void GetKey(char k[8]);
    17     //生成16个子密钥
    18     void generateKeys();
    19 
    20     void encrypt(const char input[8], char output[8]);
    21     void decrypt(const char input[8], char output[8]);
    22 
    23     void StrEncrypt(string plaintext, string &ciphertext);
    24     void StrDecrypt(string ciphertext, string &output);
    25 
    26 private:
    27     bitset<64> key;                // 64位密钥  
    28     bitset<48> subKey[16];         // K1~K16子密钥 
    29     bitset<64> plain;
    30     bitset<64> cipher;
    31 
    32     bitset<64> charToBitset(const char s[8]);
    33     void bitToChar(bitset<64> bits, char c[8]);
    34 
    35     //圈函数
    36     bitset<32> f(bitset<32> R, bitset<48> k);
    37     bitset<28> leftShift(bitset<28> k, int shift);
    38 
    39 };
    40 
    41 #endif
      1 #include "DES.h"
      2 
      3 //IP置换表  
      4 int IP[] = {
      5     58, 50, 42, 34, 26, 18, 10, 2,
      6     60, 52, 44, 36, 28, 20, 12, 4,
      7     62, 54, 46, 38, 30, 22, 14, 6,
      8     64, 56, 48, 40, 32, 24, 16, 8,
      9     57, 49, 41, 33, 25, 17, 9, 1,
     10     59, 51, 43, 35, 27, 19, 11, 3,
     11     61, 53, 45, 37, 29, 21, 13, 5,
     12     63, 55, 47, 39, 31, 23, 15, 7 };
     13 
     14 //IP-1置换表  
     15 int IP_1[] = {
     16     40, 8, 48, 16, 56, 24, 64, 32,
     17     39, 7, 47, 15, 55, 23, 63, 31,
     18     38, 6, 46, 14, 54, 22, 62, 30,
     19     37, 5, 45, 13, 53, 21, 61, 29,
     20     36, 4, 44, 12, 52, 20, 60, 28,
     21     35, 3, 43, 11, 51, 19, 59, 27,
     22     34, 2, 42, 10, 50, 18, 58, 26,
     23     33, 1, 41, 9, 49, 17, 57, 25 };
     24 
     25 //将64位密钥变成56位  
     26 int PC_1[] = {
     27     57, 49, 41, 33, 25, 17, 9,
     28     1, 58, 50, 42, 34, 26, 18,
     29     10, 2, 59, 51, 43, 35, 27,
     30     19, 11, 3, 60, 52, 44, 36,
     31     63, 55, 47, 39, 31, 23, 15,
     32     7, 62, 54, 46, 38, 30, 22,
     33     14, 6, 61, 53, 45, 37, 29,
     34     21, 13, 5, 28, 20, 12, 4 };
     35 
     36 //将56位密钥压缩成48位子密钥  
     37 int PC_2[] = {
     38     14, 17, 11, 24, 1, 5,
     39     3, 28, 15, 6, 21, 10,
     40     23, 19, 12, 4, 26, 8,
     41     16, 7, 27, 20, 13, 2,
     42     41, 52, 31, 37, 47, 55,
     43     30, 40, 51, 45, 33, 48,
     44     44, 49, 39, 56, 34, 53,
     45     46, 42, 50, 36, 29, 32 };
     46 
     47 //每轮左移的位数  
     48 int shiftBits[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
     49 
     50 //E置换表,将32位扩展至48位  
     51 int E[] = {
     52     32, 1, 2, 3, 4, 5,
     53     4, 5, 6, 7, 8, 9,
     54     8, 9, 10, 11, 12, 13,
     55     12, 13, 14, 15, 16, 17,
     56     16, 17, 18, 19, 20, 21,
     57     20, 21, 22, 23, 24, 25,
     58     24, 25, 26, 27, 28, 29,
     59     28, 29, 30, 31, 32, 1 };
     60 
     61 //S盒 4x16 
     62 int S_BOX[8][4][16] = {
     63     {
     64         { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
     65         { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
     66         { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
     67         { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
     68     },
     69     {
     70         { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
     71         { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
     72         { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
     73         { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
     74     },
     75     {
     76         { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
     77         { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
     78         { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
     79         { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
     80     },
     81     {
     82         { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
     83         { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
     84         { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
     85         { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
     86     },
     87     {
     88         { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
     89         { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
     90         { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
     91         { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
     92     },
     93     {
     94         { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
     95         { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
     96         { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
     97         { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
     98     },
     99     {
    100         { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
    101         { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
    102         { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
    103         { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
    104     },
    105     {
    106         { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
    107         { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
    108         { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
    109         { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
    110     }
    111 };
    112 
    113 //P置换
    114 int P[] = {
    115     16, 7, 20, 21,
    116     29, 12, 28, 17,
    117     1, 15, 23, 26,
    118     5, 18, 31, 10,
    119     2, 8, 24, 14,
    120     32, 27, 3, 9,
    121     19, 13, 30, 6,
    122     22, 11, 4, 25 };
    123 
    124 
    125 //密码函数f,接收32位数据和48位子密钥,产生一个32位的输出
    126 bitset<32> DES::f(bitset<32> R, bitset<48> k)
    127 {
    128     bitset<48> expandR;
    129     //E 
    130     for (int i = 0; i<48; ++i)
    131         expandR[47 - i] = R[32 - E[i]];
    132     //异或  
    133     expandR = expandR ^ k;
    134     //查找S_BOX 
    135     bitset<32> output;
    136     int x = 0;
    137     //48 bit分为8组
    138     for (int i = 0; i<48; i = i + 6)
    139     {
    140         // i = x1x6 + 1 
    141         int row = expandR[47 - i] * 2 + expandR[47 - i - 5];
    142         // j = x2x3x4x5 + 1
    143         int col = expandR[47 - i - 1] * 8 + expandR[47 - i - 2] * 4 + expandR[47 - i - 3] * 2 + expandR[47 - i - 4];
    144         //每个S-盒
    145         int num = S_BOX[i / 6][row][col];
    146         //转化为bit
    147         bitset<4> binary(num);
    148         output[31 - x] = binary[3];
    149         output[31 - x - 1] = binary[2];
    150         output[31 - x - 2] = binary[1];
    151         output[31 - x - 3] = binary[0];
    152         x += 4;
    153     }
    154     //P置换
    155     bitset<32> tmp = output;
    156     for (int i = 0; i<32; ++i)
    157         output[31 - i] = tmp[32 - P[i]];
    158     return output;
    159 }
    160 
    161 //对56位密钥的前后部分进行左移
    162 bitset<28> DES::leftShift(bitset<28> k, int shift)
    163 {
    164     bitset<28> tmp = k;
    165     for (int i = 27; i >= 0; --i)
    166     {
    167         if (i - shift<0)
    168             k[i] = tmp[i - shift + 28];
    169         else
    170             k[i] = tmp[i - shift];
    171     }
    172     return k;
    173 }
    174 
    175 void DES::GetKey(char k[8])
    176 {
    177     key = charToBitset(k);
    178 }
    179 
    180 //将char字符数组转为二进制
    181 bitset<64> DES::charToBitset(const char s[8])
    182 {
    183     bitset<64> bits;
    184     for (unsigned i = 0; i < 8; ++i)
    185     for (unsigned j = 0; j < 8; ++j)
    186         bits[i * 8 + j] = ((s[i] >> j) & 1);
    187     return bits;
    188 }
    189 
    190 //将二进制转为char字符数组
    191 void DES::bitToChar(bitset<64> bits, char c[8])
    192 {
    193     for (int j = 0; j < 8; j++)
    194         c[j] = 0;
    195     for (unsigned i = 0; i < 64; i++)
    196     {
    197         if (bits.test(i))    //该位是否为1
    198             c[i / 8] |= 1 << (i % 8);
    199     }
    200 }
    201 
    202 //生成16个子密钥
    203 void DES::generateKeys()
    204 {
    205     bitset<56> realKey;
    206     bitset<28> left;
    207     bitset<28> right;
    208     bitset<48> compressKey;
    209 
    210     // 去掉奇偶标记位,将64位密钥变成56位  
    211     for (int i = 0; i<56; ++i)
    212         realKey[55 - i] = key[64 - PC_1[i]];
    213     // 生成子密钥,保存在 subKeys[16] 中  
    214     for (int round = 0; round<16; ++round)
    215     {
    216         // 前28位与后28位  
    217         for (int i = 28; i<56; ++i)
    218             left[i - 28] = realKey[i];
    219         for (int i = 0; i<28; ++i)
    220             right[i] = realKey[i];
    221         // 左移  
    222         left = leftShift(left, shiftBits[round]);
    223         right = leftShift(right, shiftBits[round]);
    224         // 压缩置换,由56位得到48位子密钥  
    225         for (int i = 28; i<56; ++i)
    226             realKey[i] = left[i - 28];
    227         for (int i = 0; i<28; ++i)
    228             realKey[i] = right[i];
    229         for (int i = 0; i<48; ++i)
    230             compressKey[47 - i] = realKey[56 - PC_2[i]];
    231         subKey[round] = compressKey;
    232     }
    233     /*cout << endl << "16个子密钥:" << endl;
    234     for (int i = 0; i < 16; i++)
    235     {
    236         cout << subKey[i] << endl;
    237     }
    238     cout << endl;*/
    239 }
    240 
    241 //DES加密
    242 void DES::encrypt(const char input[8], char output[8])
    243 {
    244     bitset<64> currentBits;
    245     bitset<32> left;
    246     bitset<32> right;
    247     bitset<32> newLeft;
    248 
    249     plain = charToBitset(input);
    250     //初始置换IP  
    251     for (int i = 0; i<64; ++i)
    252         currentBits[63 - i] = plain[64 - IP[i]];
    253     //获取 Li 和 Ri  
    254     for (int i = 32; i<64; ++i)
    255         left[i - 32] = currentBits[i];
    256     for (int i = 0; i<32; ++i)
    257         right[i] = currentBits[i];
    258     //16轮迭代  
    259     for (int round = 0; round<16; ++round)
    260     {
    261         newLeft = right;
    262         right = left ^ f(right, subKey[round]);
    263         left = newLeft;
    264     }
    265     //合并L16和R16,合并为R16L16   
    266     for (int i = 0; i<32; ++i)
    267         cipher[i] = left[i];
    268     for (int i = 32; i<64; ++i)
    269         cipher[i] = right[i - 32];
    270     //尾置换IP-1  
    271     currentBits = cipher;
    272     for (int i = 0; i<64; ++i)
    273         cipher[63 - i] = currentBits[64 - IP_1[i]];
    274 
    275     bitToChar(cipher, output);
    276     /*cout << "得到密文:" ;
    277     for (int i = 0; i < 8; i++)
    278         cout << output[i] << endl;*/
    279 }
    280 //DES解密
    281 void DES::decrypt(const char input[8], char output[8])
    282 {
    283     bitset<64> currentBits;
    284     bitset<32> left;
    285     bitset<32> right;
    286     bitset<32> newLeft;
    287 
    288     cipher = charToBitset(input);
    289     //初始置换IP  
    290     for (int i = 0; i<64; ++i)
    291         currentBits[63 - i] = cipher[64 - IP[i]];
    292     //获取 Li 和 Ri  
    293     for (int i = 32; i<64; ++i)
    294         left[i - 32] = currentBits[i];
    295     for (int i = 0; i<32; ++i)
    296         right[i] = currentBits[i];
    297     //共16轮迭代(子密钥逆序应用)  
    298     for (int round = 0; round<16; ++round)
    299     {
    300         newLeft = right;
    301         right = left ^ f(right, subKey[15 - round]);
    302         left = newLeft;
    303     }
    304     //合并L16和R16,合并为R16L16  
    305     for (int i = 0; i<32; ++i)
    306         plain[i] = left[i];
    307     for (int i = 32; i<64; ++i)
    308         plain[i] = right[i - 32];
    309     //尾置换IP-1  
    310     currentBits = plain;
    311     for (int i = 0; i<64; ++i)
    312         plain[63 - i] = currentBits[64 - IP_1[i]];
    313  
    314     bitToChar(plain, output);
    315     /*cout << "得到密文解:";
    316     for (int i = 0; i < 8; i++)
    317         cout << output[i] << endl;*/
    318 }
    319 
    320 //string任意长明文加密
    321 void DES::StrEncrypt(string plaintext, string &ciphertext)
    322 {
    323     char output[8];
    324     string stradd = "        ";
    325     string per = output;
    326     int length = plaintext.length();
    327     if (length % 8 != 0)
    328     {//明文不是8的倍数,用空格填充
    329         plaintext.append(stradd, 0, 8 - length % 8);
    330     }
    331     length = plaintext.length();
    332     for (int i = 0; i < length; i += 8)
    333     {
    334         per = plaintext.substr(i, 8);
    335         encrypt(per.c_str(),output);
    336         per = output;
    337         ciphertext += per.substr(0,8);
    338     }
    339 }
    340 
    341 //string任意长密文解密
    342 void DES::StrDecrypt(string ciphertext, string &output)
    343 {
    344     char out[8];
    345     string per = out;
    346     int length = ciphertext.length();
    347     for (int i = 0; i < length; i += 8)
    348     {
    349         per = ciphertext.substr(i, 8);
    350         decrypt(per.c_str(), out);
    351         per = out;
    352         output += per.substr(0,8);
    353     }
    354 }
     1 #include <iostream>   
     2 #include <string>
     3 #include "DES.h"
     4 using namespace std;
     5 
     6 
     7 int main()
     8 {
     9     DES des;
    10     char key[8];
    11     string k;
    12     string plaintext, ciphertext, output;
    13     
    14     cout << "输入明文: ";
    15     cin >> plaintext;
    16     cout << "输入密钥: ";
    17     for (int i = 0; i < 8; i++)
    18         cin >> key[i];
    19     des.GetKey(key);
    20     des.generateKeys();    
    21 
    22     des.StrEncrypt(plaintext, ciphertext);
    23     cout << endl << "输出密文: " << ciphertext.c_str() << endl;
    24     des.StrDecrypt(ciphertext, output);
    25     cout << endl << "解密密文: " << output.c_str() << endl;
    26 
    27     cout << endl;
    28     return 0;
    29 }
  • 相关阅读:
    《痕迹识人,面试读心》培训总结之一
    傲游与视频网站广告之战的思考
    EMLS项目推进思考
    二级证丢失如何找回
    Mathematica 讲座
    泊松方程解法
    Windows核心编程-作业
    Win7多用户同时登陆
    C语言文件操作类型速查
    openMP的一点使用经验
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4328268.html
Copyright © 2020-2023  润新知