• C++ Base64 编码 解码


    C++实现 base64 字符串编码解码(GCC编译)。

      1 /**
      2 * @brief C++ base64 编解码
      3 * @author wid
      4 * @date 2013-20-25
      5 *
      6 * @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢!
      7 */
      8 
      9 #include <iostream>
     10 #include <string>
     11 #include <ctime>
     12 
     13 //base64 编解码函数声明
     14 std::string b64encodestring(const std::string &strString);      //对 ASCII 字符串进行 base64 编码
     15 std::string b64decodestring(const std::string &strString);      //对 base64 编码后的字符串进行解码
     16 
     17 //base64 编解码函数实现
     18 /**
     19 * @brief 对 ASCII 字符串进行 base64 编码
     20 *
     21 * @param strString 待编码的字符串
     22 *
     23 * @return srs::string 返回编码后的字符串
     24 *
     25 * @note 对于字符串中含有非 ASCII 字符串型的字符, 代码将抛出 std::string 型异常, 请捕获
     26 */
     27 std::string b64encodestring(const std::string &strString)
     28 {
     29     int nByteSrc = strString.length();
     30     std::string pszSource = strString;
     31 
     32     int i = 0;
     33     for(i; i < nByteSrc; i++)
     34         if( pszSource[i] < 0 || pszSource[i] > 127 )
     35             throw "can not encode Non-ASCII characters";
     36 
     37     const char *enkey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     38     std::string pszEncode(nByteSrc*4/3 + 4, '');
     39     int nLoop = nByteSrc %3 == 0 ? nByteSrc : nByteSrc - 3;
     40     int n = 0;
     41     for(i=0; i < nLoop; i+=3 )
     42     {
     43         pszEncode[n] = enkey[pszSource[i]>>2];
     44         pszEncode[n+1] = enkey[((pszSource[i]&3)<<4) | ((pszSource[i+1] & 0xF0)>>4)];
     45         pszEncode[n+2] = enkey[((pszSource[i+1] & 0x0f)<<2) | ((pszSource[i+2] & 0xc0 )>>6)];
     46         pszEncode[n+3] = enkey[pszSource[i+2] & 0x3F];
     47         n += 4;
     48     }
     49 
     50     switch(nByteSrc%3)
     51     {
     52     case 0:
     53         pszEncode[n] = '';
     54         break;
     55 
     56     case 1:
     57         pszEncode[n] = enkey[pszSource[i]>>2];
     58         pszEncode[n+1] = enkey[((pszSource[i]&3)<<4) | ((0&0xf0)>>4)];
     59         pszEncode[n+2] = '=';
     60         pszEncode[n+3] = '=';
     61         pszEncode[n+4] = '';
     62         break;
     63 
     64     case 2:
     65         pszEncode[n] = enkey[pszSource[i]>>2];
     66         pszEncode[n+1] = enkey[((pszSource[i]&3)<<4) | ((pszSource[i+1]&0xf0)>>4)];
     67         pszEncode[n+2] = enkey[(( pszSource[i+1]&0xf)<<2 ) | ((0&0xc0)>>6)];
     68         pszEncode[n+3] = '=';
     69         pszEncode[n+4] = '';
     70         break;
     71     }
     72 
     73     return pszEncode.c_str();
     74 }
     75 
     76 /**
     77 * @brief 对 base64 编码后的字符串进行解码
     78 *
     79 * @param strString 待解码的字符串
     80 *
     81 * @return std::string 返回解码后的字符串
     82 *
     83 * @note 对于非base64编码的字符串或已损坏的base64字符串进行解码会抛出 std::string 型异常, 请捕获
     84 */
     85 std::string b64decodestring(const std::string &strString)
     86 {
     87     int nByteSrc = strString.length();
     88     std::string pszSource = strString;
     89 
     90     const int dekey[] = {
     91         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     92         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     93         62, // '+'
     94         -1, -1, -1,
     95         63, // '/'
     96         52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
     97         -1, -1, -1, -1, -1, -1, -1,
     98         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
     99         13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
    100         -1, -1, -1, -1, -1, -1,
    101         26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
    102         39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
    103     };
    104 
    105     if(nByteSrc%4 != 0)
    106         throw "bad base64 string";
    107 
    108     std::string pszDecode(nByteSrc*3/4+4, '');
    109     int nLoop = pszSource[nByteSrc-1]  == '=' ? nByteSrc - 4 : nByteSrc;
    110     int b[4];
    111     int i = 0, n = 0;
    112     for(i = 0; i < nLoop; i += 4 )
    113     {
    114         b[0] = dekey[pszSource[i]];        b[1] = dekey[pszSource[i+1]];
    115         b[2] = dekey[pszSource[i+2]];    b[3] = dekey[pszSource[i+3]];
    116         if(b[0] == -1 || b[1] == -1 || b[2] == -1 || b[3] == -1)
    117             throw "bad base64 string";
    118 
    119         pszDecode[n] = (b[0] << 2) | ((b[1] & 0x30) >> 4);
    120         pszDecode[n+1] = ((b[1] & 0xf) << 4) | ((b[2] & 0x3c) >> 2);
    121         pszDecode[n+2] =  ((b[2] & 0x3) << 6) | b[3];
    122 
    123         n+=3;
    124     }
    125 
    126     if( pszSource[nByteSrc-1] == '=' && pszSource[nByteSrc-2] == '=' )
    127     {
    128         b[0] = dekey[pszSource[i]];        b[1] = dekey[pszSource[i+1]];
    129         if(b[0] == -1 || b[1] == -1)
    130             throw "bad base64 string";
    131 
    132         pszDecode[n] = (b[0] << 2) | ((b[1] & 0x30) >> 4);
    133         pszDecode[n+1] = '';
    134     }
    135 
    136     if( pszSource[nByteSrc-1] == '=' && pszSource[nByteSrc-2] != '=' )
    137     {
    138         b[0] = dekey[pszSource[i]];        b[1] = dekey[pszSource[i+1]];
    139         b[2] = dekey[pszSource[i+2]];
    140         if(b[0] == -1 || b[1] == -1 || b[2] == -1)
    141             throw "bad base64 string";
    142 
    143         pszDecode[n] = (b[0] << 2) | ((b[1] & 0x30) >> 4);
    144         pszDecode[n+1] = ((b[1] & 0xf) << 4) | ((b[2] & 0x3c) >> 2);
    145         pszDecode[n+2] = '';
    146     }
    147 
    148     if( pszSource[nByteSrc-1] != '=' && pszSource[nByteSrc-2] != '=' )
    149         pszDecode[n] = '';
    150 
    151     return pszDecode;
    152 }
    153 
    154 //测试
    155 int main()
    156 {
    157     ///编码测试
    158     std::string str1 = "Hello, world!";
    159     std::cout << "对Hello, world!进行base64编码: " << b64encodestring(str1) << std::endl;
    160 
    161     ///解码测试
    162     std::string str2 = "SGVsbG8sIHdvcmxkIQ==";
    163     std::cout << "对SGVsbG8sIHdvcmxkIQ==进行base64解码: " << b64decodestring(str2) << std::endl;
    164 
    165     ///编码耗时测试
    166     std::string str3(10000000, 'A');    //生成 10000000 长的字符串
    167     std::cout << std::endl << "对 10000000 长的字符串进行编码耗时测试.." << std::endl;
    168     size_t t0 = clock();        //编码计时开始
    169     b64encodestring(str3);
    170     std::cout << "测试结束, 耗时 " << clock() - t0 << "ms" << std::endl;
    171 
    172     ///解码耗时测试
    173     std::string str4 = b64encodestring(str3);        //得到长度为 10000000 的字符串base64编码后的字符串
    174     std::cout << std::endl << "" << str4.length() << " 长的base64字符串进行解码耗时测试.." << std::endl;
    175     size_t t1 = clock();        //解码计时开始
    176     b64decodestring(str3);
    177     std::cout << "测试结束, 耗时 " << clock() - t1 << "ms" << std::endl;
    178 
    179     return 0;
    180 }

    运行测试结果:

    若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢。                                                                                                                                                                                                                                                                                                                                                  

  • 相关阅读:
    CentOS7安装minio
    xshell连接虚拟机Connection failed
    Mysql时间加减函数
    mysql存储过程模板
    Activiti实现会签功能
    2018考研复试流程
    C编程经验总结5(剧终)
    《数据结构总结》
    《关于安卓和IOS开发》
    番外特别篇之 为什么我不建议你直接使用UIImage传值?--从一个诡异的相册九图连读崩溃bug谈起
  • 原文地址:https://www.cnblogs.com/mr-wid/p/3388719.html
Copyright © 2020-2023  润新知