base64編碼,和url安全的base64編碼html
通過base64編碼後的字符串長度(包含結束符):(src_len+2)*4/3 +1express
RFC4648:https://tools.ietf.org/html/rfc4648安全
1 int base64_encode(const unsigned char* in_str, int in_len, unsigned char* out_str); 2 int base64_decode(const unsigned char* in_str, int in_len, unsigned char* out_str); 3 4 int base64_url_encode(const unsigned char* in_str, int in_len, unsigned char* out_str); 5 int base64_url_decode(const unsigned char* in_str, int in_len, unsigned char* out_str);
實現app
1 /* 2 General utilities : Base64 encode/decode helper class 3 4 Copyright (c) 2003 by Morning 5 http://morningspace.51.net 6 mailto:moyingzz@etang.com 7 8 Permission to use, copy, modify, distribute and sell this program for any 9 purpose is hereby granted without fee, provided that the above copyright 10 notice appear in all copies and that both that copyright notice and this 11 permission notice appear in supporting documentation. 12 13 It is provided "as is" without express or implied warranty. */ 14 15 #include "bobo_base64.h" 16 17 const char* _base64_encode_chars = 18 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 19 20 const char _base64_decode_chars[] = 21 { 22 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 25 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, 26 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 27 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 28 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 29 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, 30 31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 34 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 35 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 36 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 37 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 38 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 39 }; 40 41 //RFC 4648 without pad 42 const char* _base64_url_encode_chars = 43 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; 44 45 const char _base64_url_decode_chars[] = 46 { 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 48 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //16-31 49 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, //32-47 50 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, //48-63 51 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //64-79 52 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, //80-95 53 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //96-111 54 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, //112-127 55 56 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 57 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 58 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 59 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 61 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 62 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 63 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0-15 64 }; 65 66 67 int base64_encode(const unsigned char* in_str,int in_len, unsigned char* out_str) 68 { 69 unsigned char c1, c2, c3; 70 int i = 0; 71 int index = 0; 72 73 while ( i<in_len ) 74 { 75 /* read the first byte */ 76 c1 = in_str[i++]; 77 if ( i==in_len ) /* pad with "="*/ 78 { 79 out_str[index++] = _base64_encode_chars[ c1>>2 ]; 80 out_str[index++] = _base64_encode_chars[ (c1&0x3)<<4 ]; 81 out_str[index++] = '='; 82 out_str[index++] = '='; 83 break; 84 } 85 86 /* read the second byte 87 */ 88 c2 = in_str[i++]; 89 if ( i==in_len ) /* pad with "=" */ 90 { 91 out_str[index++] = _base64_encode_chars[ c1>>2 ]; 92 out_str[index++] = _base64_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ]; 93 out_str[index++] = _base64_encode_chars[ (c2&0xF)<<2 ]; 94 out_str[index++] = '='; 95 break; 96 } 97 98 /* read the third byte */ 99 c3 = in_str[i++]; 100 /* convert into four bytes string */ 101 out_str[index++] = _base64_encode_chars[ c1>>2 ]; 102 out_str[index++] = _base64_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ]; 103 out_str[index++] = _base64_encode_chars[ ((c2&0xF)<<2) | ((c3&0xC0)>>6) ]; 104 out_str[index++] = _base64_encode_chars[ c3&0x3F ]; 105 } 106 107 return index; 108 } 109 110 int base64_decode(const unsigned char* in_str, int in_len, unsigned char* out_str) 111 { 112 char c1, c2, c3, c4; 113 int i = 0; 114 int index = 0; 115 116 while ( i<in_len) 117 { 118 /* read the first byte */ 119 do { 120 c1 = _base64_decode_chars[ (int)in_str[i++] ]; 121 } while ( i<in_len && c1==-1); 122 123 if ( c1==-1) 124 break; 125 126 /* read the second byte */ 127 do { 128 c2 = _base64_decode_chars[ (int)in_str[i++] ]; 129 } while ( i<in_len && c2==-1); 130 131 if ( c2==-1 ) 132 break; 133 134 /* assamble the first byte */ 135 out_str[index++] = (char)( (c1<<2) | ((c2&0x30)>>4) ); 136 137 /* read the third byte */ 138 do { 139 c3 = in_str[i++]; 140 if ( c3==61 ) /* meet with "=", break */ 141 return index; 142 c3 = _base64_decode_chars[ (int)c3 ]; 143 } while ( i<in_len && c3==-1); 144 145 if ( c3==-1 ) 146 break; 147 148 /* assabmel the second byte */ 149 out_str[index++] = (char)( ((c2&0XF)<<4) | ((c3&0x3C)>>2) ); 150 151 /* read the fourth byte */ 152 do { 153 c4 = in_str[i++]; 154 if ( c4==61 ) /* meet with "=", break */ 155 return index; 156 c4 = _base64_decode_chars[ (int)c4 ]; 157 } while ( i<in_len && c4==-1 ); 158 159 if ( c4==-1 ) 160 break; 161 162 /* assamble the third byte */ 163 out_str[index++] = (char)( ((c3&0x03)<<6) | c4 ); 164 } 165 166 return index; 167 } 168 169 int base64_url_encode(const unsigned char* in_str, int in_len, unsigned char* out_str) 170 { 171 unsigned char c1, c2, c3; 172 int i = 0; 173 int index = 0; 174 const int split = 3; 175 176 int group = in_len/split; 177 int mod = in_len%split; 178 179 for (int j=0; j<group; ++j) 180 {//每次處理3字節 181 c1 = in_str[i++]; 182 c2 = in_str[i++]; 183 c3 = in_str[i++]; 184 185 out_str[index++] = _base64_url_encode_chars[ c1>>2 ]; 186 out_str[index++] = _base64_url_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ]; 187 out_str[index++] = _base64_url_encode_chars[ ((c2&0xF)<<2) | ((c3&0xC0)>>6) ]; 188 out_str[index++] = _base64_url_encode_chars[ c3&0x3F ]; 189 } 190 191 //處理剩餘的 192 if (mod == 1) 193 { 194 c1 = in_str[i++]; 195 196 out_str[index++] = _base64_url_encode_chars[ c1>>2 ]; 197 out_str[index++] = _base64_url_encode_chars[ (c1&0x3)<<4 ]; 198 } 199 else if (mod == 2) 200 { 201 c1 = in_str[i++]; 202 c2 = in_str[i++]; 203 204 out_str[index++] = _base64_url_encode_chars[ c1>>2 ]; 205 out_str[index++] = _base64_url_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ]; 206 out_str[index++] = _base64_url_encode_chars[ (c2&0xF)<<2 ]; 207 } 208 209 return index; 210 } 211 212 int base64_url_decode(const unsigned char* in_str, int in_len, unsigned char* out_str) 213 { 214 unsigned char c1, c2, c3, c4; 215 int i = 0; 216 int index = 0; 217 218 const int split = 4; 219 220 int group = in_len/split; 221 int mod = in_len%split; 222 223 for (int j=0; j<group; ++j) 224 { 225 c1 = _base64_url_decode_chars[in_str[i++]]; 226 c2 = _base64_url_decode_chars[in_str[i++]]; 227 c3 = _base64_url_decode_chars[in_str[i++]]; 228 c4 = _base64_url_decode_chars[in_str[i++]]; 229 230 out_str[index++] = ( (c1<<2) | ((c2&0x30)>>4) ); 231 out_str[index++] = ( ((c2&0XF)<<4) | ((c3&0x3C)>>2) ); 232 out_str[index++] = ( ((c3&0x03)<<6) | c4 ); 233 } 234 235 switch (mod) 236 { 237 case 0: 238 break; 239 case 1://錯誤 240 break; 241 case 2: 242 c1 = _base64_url_decode_chars[in_str[i++]]; 243 c2 = _base64_url_decode_chars[in_str[i++]]; 244 out_str[index++] = ( (c1<<2) | ((c2&0x30)>>4) ); 245 break; 246 case 3: 247 c1 = _base64_url_decode_chars[in_str[i++]]; 248 c2 = _base64_url_decode_chars[in_str[i++]]; 249 c3 = _base64_url_decode_chars[in_str[i++]]; 250 251 out_str[index++] = ( (c1<<2) | ((c2&0x30)>>4) ); 252 out_str[index++] = ( ((c2&0XF)<<4) | ((c3&0x3C)>>2) ); 253 254 break; 255 } 256 257 return index; 258 }