base64.c

Go to the documentation of this file.
00001 /*  Copyright (c) 2006-2007, Philip Busch <broesel@studcs.uni-sb.de>
00002  *  All rights reserved.
00003  *
00004  *  Redistribution and use in source and binary forms, with or without
00005  *  modification, are permitted provided that the following conditions are met:
00006  *
00007  *   - Redistributions of source code must retain the above copyright notice,
00008  *     this list of conditions and the following disclaimer.
00009  *   - Redistributions in binary form must reproduce the above copyright
00010  *     notice, this list of conditions and the following disclaimer in the
00011  *     documentation and/or other materials provided with the distribution.
00012  *
00013  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00014  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00015  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00016  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00017  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00018  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00019  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00020  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00021  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00022  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00023  *  POSSIBILITY OF SUCH DAMAGE.
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 

Generated on Thu Jul 19 13:36:09 2007 for libv by  doxygen 1.5.1-p1. Thank you, SourceForge.net Logo