base64编码

base64编码,和url安全的base64编码

经过base64编码后的字符串长度(包含结束符):(src_len+2)*4/3 +1

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);

 

实现

 

  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 }

 

posted on 2019-03-25 18:15  lijianbo  阅读(196)  评论(0编辑  收藏  举报

导航