16 #include <my_global.h>
23 static char base64_table[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
24 "abcdefghijklmnopqrstuvwxyz"
32 base64_encode_max_arg_length()
39 return 0x5EC0D4C77B03531BLL
51 base64_needed_encoded_length(
int length_of_data)
54 nb_base64_chars= (length_of_data + 2) / 3 * 4;
58 (nb_base64_chars - 1)/ 76 +
68 base64_decode_max_arg_length()
71 return 0x2AAAAAAAAAAAAAAALL;
79 base64_needed_decoded_length(
int length_of_encoded_data)
81 return (
int) ceil(length_of_encoded_data * 3 / 4);
93 base64_encode(
const void *src,
size_t src_len,
char *dst)
95 const unsigned char *s= (
const unsigned char*)src;
99 for (; i < src_len; len += 4)
121 *dst++= base64_table[(c >> 18) & 0x3f];
122 *dst++= base64_table[(c >> 12) & 0x3f];
124 if (i > (src_len + 1))
127 *dst++= base64_table[(c >> 6) & 0x3f];
132 *dst++= base64_table[(c >> 0) & 0x3f];
163 -1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-1,-1,
164 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
165 -2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
166 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
167 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
168 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
169 -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
170 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
171 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
172 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
173 -2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
174 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
175 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
176 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
177 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
178 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
196 static inline my_bool
199 for ( ; decoder->src < decoder->end; decoder->src++)
201 if (from_base64_table[(uchar) *decoder->src] != -2)
204 if (decoder->state > 0)
221 static inline my_bool
226 if ((res= from_base64_table[(uchar) *decoder->src++]) < 0)
227 return (decoder->error= TRUE);
228 decoder->c+= (uint) res;
243 static inline my_bool
246 if (my_base64_decoder_skip_spaces(decoder))
249 if (!my_base64_add(decoder))
254 DBUG_ASSERT(decoder->state == 3);
264 switch (decoder->state)
274 if (decoder->src[-1] ==
'=')
317 base64_decode(
const char *src_base,
size_t len,
318 void *dst,
const char **end_ptr,
int flags)
320 char *d= (
char*) dst;
323 decoder.src= src_base;
324 decoder.end= src_base + len;
333 if (my_base64_decoder_getch(&decoder) ||
334 my_base64_decoder_getch(&decoder) ||
335 my_base64_decoder_getch(&decoder) ||
336 my_base64_decoder_getch(&decoder))
339 *d++= (decoder.c >> 16) & 0xff;
340 *d++= (decoder.c >> 8) & 0xff;
341 *d++= (decoder.c >> 0) & 0xff;
346 if (!(flags & MY_BASE64_DECODE_ALLOW_MULTIPLE_CHUNKS))
354 if (!my_base64_decoder_skip_spaces(&decoder))
358 *end_ptr= decoder.src;
360 return decoder.error ? -1 : (int) (d - (
char*) dst);
366 #define require(b) { \
368 printf("Require failed at %s:%d\n", __FILE__, __LINE__); \
381 size_t needed_length;
383 for (i= 0; i < 500; i++)
386 const size_t src_len= rand() % 1000 + 1;
388 char * src= (
char *) malloc(src_len);
394 for (j= 0; j<src_len; j++)
401 needed_length= base64_needed_encoded_length(src_len);
402 str= (
char *) malloc(needed_length);
404 for (k= 0; k < needed_length; k++)
406 require(base64_encode(src, src_len, str) == 0);
407 require(needed_length == strlen(str) + 1);
410 dst= (
char *) malloc(base64_needed_decoded_length(strlen(str)));
412 dst_len= base64_decode(str, strlen(str), dst, NULL);
413 require(dst_len == src_len);
415 if (memcmp(src, dst, src_len) != 0)
417 printf(
" --------- src --------- --------- dst ---------\n");
418 for (k= 0; k<src_len; k+=8)
420 printf(
"%.4x ", (uint) k);
421 for (l=0; l<8 && k+l<src_len; l++)
423 unsigned char c= src[k+l];
424 printf(
"%.2x ", (
unsigned)c);
429 for (l=0; l<8 && k+l<dst_len; l++)
431 unsigned char c= dst[k+l];
432 printf(
"%.2x ", (
unsigned)c);
436 printf(
"src length: %.8x, dst length: %.8x\n",
437 (uint) src_len, (uint) dst_len);
441 printf(
"Test succeeded.\n");