C++ Base64 编码 解码
2013-10-25 22:51 wid 阅读(8862) 评论(4) 编辑 收藏 举报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, '\0'); 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] = '\0'; 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] = '\0'; 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] = '\0'; 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, '\0'); 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] = '\0'; 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] = '\0'; 146 } 147 148 if( pszSource[nByteSrc-1] != '=' && pszSource[nByteSrc-2] != '=' ) 149 pszDecode[n] = '\0'; 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 或程序缺陷, 请留言反馈, 谢谢。