00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include "base64.h"
00036
00037 #define XX 100
00038
00069 static const char base64_list[] = \
00070 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00071
00072 static const int base64_index[256] = {
00073 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00074 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00075 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63,
00076 52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,XX,XX,XX,
00077 XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
00078 15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
00079 XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
00080 41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
00081 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00082 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00083 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00084 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00085 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00086 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00087 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00088 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
00089 };
00090
00105 void base64_encode_block(unsigned char out[4], const unsigned char in[3], int len)
00106 {
00107 out[0] = base64_list[ in[0] >> 2 ];
00108 out[1] = base64_list[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
00109 out[2] = (unsigned char) (len > 1 ? base64_list[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
00110 out[3] = (unsigned char) (len > 2 ? base64_list[in[2] & 0x3f] : '=');
00111 }
00112
00126 int base64_decode_block(unsigned char out[3], const unsigned char in[4])
00127 {
00128 int i, numbytes = 3;
00129 char tmp[4];
00130
00131 for(i = 3; i >= 0; i--) {
00132 if(in[i] == '=') {
00133 tmp[i] = 0;
00134 numbytes = i - 1;
00135 } else {
00136 tmp[i] = base64_index[ (unsigned char)in[i] ];
00137 }
00138
00139 if(tmp[i] == XX)
00140 return(-1);
00141 }
00142
00143 out[0] = (unsigned char) ( tmp[0] << 2 | tmp[1] >> 4);
00144 out[1] = (unsigned char) ( tmp[1] << 4 | tmp[2] >> 2);
00145 out[2] = (unsigned char) (((tmp[2] << 6) & 0xc0) | tmp[3]);
00146
00147 return(numbytes);
00148 }
00149
00159 size_t base64_encoded_size(size_t len)
00160 {
00161 return(((len + 2) / 3) * 4);
00162 }
00163
00174 size_t base64_decoded_size(size_t len)
00175 {
00176 return((len / 4) * 3);
00177 }
00178
00194 void base64_encode_binary(char *out, const unsigned char *in, size_t len)
00195 {
00196 int size;
00197 size_t i = 0;
00198
00199 while(i < len) {
00200 size = (len-i < 4) ? len-i : 4;
00201
00202 base64_encode_block((unsigned char *)out, in, size);
00203
00204 out += 4;
00205 in += 3;
00206 i += 3;
00207 }
00208
00209 *out = '\0';
00210 }
00211
00225 int base64_decode_binary(unsigned char *out, const char *in)
00226 {
00227 size_t len = strlen(in), i = 0;
00228 int numbytes = 0;
00229
00230 while(i < len) {
00231 if((numbytes += base64_decode_block(out, (unsigned char *)in)) < 0)
00232 return(-1);
00233
00234 out += 3;
00235 in += 4;
00236 i += 4;
00237 }
00238
00239 return(numbytes);
00240 }
00241
00255 char *base64_encode(const char *in, size_t size)
00256 {
00257 char *out;
00258 size_t outlen;
00259
00260 if(in == NULL)
00261 return(NULL);
00262
00263 if(size == 0)
00264 size = strlen(in);
00265
00266 outlen = base64_encoded_size(size);
00267
00268 if((out = (char *)malloc(sizeof(char) * (outlen + 1))) == NULL)
00269 return(NULL);
00270
00271 base64_encode_binary(out, (unsigned char *)in, size);
00272
00273 return(out);
00274 }
00275
00289 char *base64_decode(const char *in)
00290 {
00291 char *out;
00292 size_t outlen;
00293 int numbytes;
00294
00295 outlen = base64_decoded_size(strlen(in));
00296
00297 if((out = (char *)malloc(sizeof(char) * (outlen + 1))) == NULL)
00298 return(NULL);
00299
00300 if((numbytes = base64_decode_binary((unsigned char *)out, in)) < 0) {
00301 free(out);
00302 return(NULL);
00303 }
00304
00305 *(out + numbytes) = '\0';
00306
00307 return(out);
00308 }
00309