00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "stdlib.h"
00008 
00009 typedef unsigned char byte ;
00010 
00011 static int  dtable_mode = -1 ;    
00012 static byte dtable[256] ;         
00013 static int linelen = 72 ;         
00014 static int ncrlf   = 1 ;
00015 
00016 #define B64_goodchar(c) (dtable[c] != 0x80)  
00017 
00018 #define B64_EOL1 '\r'   
00019 #define B64_EOL2 '\n'   
00020 
00021 
00022 
00023 void B64_set_crlf( int nn )
00024 {
00025    if( nn >= 1 && nn <= 2 ) ncrlf = nn ;
00026    return ;
00027 }
00028 
00029 
00030 
00031 void B64_set_linelen( int ll )
00032 {
00033    if( ll >= 16 && ll <= 76 ) linelen = 4*(ll/4) ; 
00034    else                       linelen = 72 ;
00035    return ;
00036 }
00037 
00038 
00039 
00040 static void load_encode_table(void)
00041 {
00042     int i ;
00043     if( dtable_mode == 1 ) return ;
00044     for (i = 0; i < 26; i++) {
00045         dtable[i] = 'A' + i;
00046         dtable[26 + i] = 'a' + i;
00047     }
00048     for (i = 0; i < 10; i++) dtable[52 + i] = '0' + i;
00049     dtable[62] = '+'; dtable[63] = '/'; dtable_mode = 1 ;
00050     return ;
00051 }
00052 
00053 
00054 
00055 static void load_decode_table(void)
00056 {
00057     int i;
00058     if( dtable_mode == 2 ) return ;
00059     for (i = 0  ; i < 255 ; i++) dtable[i] = 0x80;             
00060     for (i = 'A'; i <= 'Z'; i++) dtable[i] =  0 + (i - 'A');
00061     for (i = 'a'; i <= 'z'; i++) dtable[i] = 26 + (i - 'a');
00062     for (i = '0'; i <= '9'; i++) dtable[i] = 52 + (i - '0');
00063     dtable['+'] = 62; dtable['/'] = 63; dtable['='] = 0; dtable_mode = 2 ;
00064     return ;
00065 }
00066 
00067 #define B64_encode3(a,b,c,w,x,y,z)                 \
00068      ( w = dtable[(a)>>2]                      ,   \
00069        x = dtable[((a & 3) << 4) | (b >> 4)]   ,   \
00070        y = dtable[((b & 0xF) << 2) | (c >> 6)] ,   \
00071        z = dtable[c & 0x3F]                     )
00072 
00073 #define B64_encode2(a,b,w,x,y,z)                   \
00074      ( B64_encode3(a,b,0,w,x,y,z) , z = '=' )
00075 
00076 #define B64_encode1(a,w,x,y,z)                     \
00077      ( B64_encode3(a,0,0,w,x,y,z) , y=z = '=' )
00078 
00079 #define B64_decode4(w,x,y,z,a,b,c)                 \
00080      ( a = (dtable[w] << 2) | (dtable[x] >> 4) ,   \
00081        b = (dtable[x] << 4) | (dtable[y] >> 2) ,   \
00082        c = (dtable[y] << 6) | dtable[z]         )
00083 
00084 #define B64_decode_count(w,x,y,z)                  \
00085      ( ((w)=='='||(x)=='=') ? 0                    \
00086                             : ((y)=='=') ? 1       \
00087                             : ((z)=='=') ? 2 : 3 )
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 void B64_to_binary( int nb64 , byte * b64 , int * nbin , byte ** bin )
00101 {
00102    int ii,jj , nn ;
00103    byte a,b,c , w,x,y,z ;
00104 
00105    
00106 
00107    if( nbin == NULL || bin == NULL ) return ;
00108 
00109    if( nb64 < 4 || b64 == NULL ){ *nbin = 0 ; *bin = NULL ; return ; }
00110 
00111    *bin = (byte *) malloc(sizeof(byte)*(2+3*nb64/4)) ;
00112    if( *bin == NULL ){ *nbin = 0 ; return ; }
00113 
00114    
00115 
00116    load_decode_table() ;
00117    for( ii=jj=0 ; ii < nb64 ; ){  
00118       w = b64[ii++] ;
00119       while( !B64_goodchar(w) && ii < nb64 ) w = b64[ii++] ;
00120       x = (ii < nb64) ? b64[ii++] : '=' ;
00121       while( !B64_goodchar(x) && ii < nb64 ) x = b64[ii++] ;
00122       y = (ii < nb64) ? b64[ii++] : '=' ;
00123       while( !B64_goodchar(y) && ii < nb64 ) y = b64[ii++] ;
00124       z = (ii < nb64) ? b64[ii++] : '=' ;
00125       while( !B64_goodchar(z) && ii < nb64 ) z = b64[ii++] ;
00126 
00127       B64_decode4(w,x,y,z,a,b,c) ;
00128 
00129       if( z == '=' ){                        
00130          nn = B64_decode_count(w,x,y,z) ;    
00131          if( nn > 0 ) (*bin)[jj++] = a ;
00132          if( nn > 1 ) (*bin)[jj++] = b ;
00133          break ;
00134       }
00135 
00136       
00137 
00138       (*bin)[jj++] = a ; (*bin)[jj++] = b ; (*bin)[jj++] = c ;
00139    }
00140 
00141    *bin  = (byte *) realloc( *bin , sizeof(byte)*jj ) ;
00142    *nbin = jj ;
00143    return ;
00144 }
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 void B64_to_base64( int nbin , byte * bin , int * nb64 , byte ** b64 )
00169 {
00170    int ii,jj , nn,n3 ;
00171    byte a,b,c , w,x,y,z ;
00172 
00173    
00174 
00175    if( nb64 == NULL || b64 == NULL ) return ;
00176    if( nbin <= 0    || bin == NULL ){ *nb64 = 0 ; *b64 = NULL ; return ; }
00177 
00178    nn   = (4.0*(linelen+ncrlf+1.0)/(3.0*linelen))*nbin + 256 ;
00179    *b64 = (byte *) malloc(sizeof(byte)*nn) ;
00180    if( *b64 == NULL ){ *nb64 = 0 ; return ; }
00181 
00182    
00183 
00184    load_encode_table() ;
00185    n3 = (nbin/3)*3 ;
00186    for( nn=jj=ii=0 ; ii < n3 ; ){
00187       a = bin[ii++] ; b = bin[ii++] ; c = bin[ii++] ;
00188       B64_encode3(a,b,c,w,x,y,z) ;
00189       (*b64)[jj++] = w ;
00190       (*b64)[jj++] = x ;
00191       (*b64)[jj++] = y ;
00192       (*b64)[jj++] = z ;
00193       nn += 4 ; if( nn >= linelen ){
00194                    if( ncrlf == 2 ) (*b64)[jj++] = B64_EOL1 ;
00195                    (*b64)[jj++] = B64_EOL2 ;
00196                    nn = 0 ;
00197                 }
00198    }
00199 
00200    
00201 
00202    if( ii < nbin ){
00203       if( ii == nbin-2 )
00204          B64_encode2(bin[ii],bin[ii+1],w,x,y,z) ;
00205       else
00206          B64_encode1(bin[ii],w,x,y,z) ;
00207 
00208       (*b64)[jj++] = w ;
00209       (*b64)[jj++] = x ;
00210       (*b64)[jj++] = y ;
00211       (*b64)[jj++] = z ; nn += 4 ;
00212    }
00213 
00214    if( nn > 0 ){
00215       if( ncrlf == 2 ) (*b64)[jj++] = B64_EOL1 ;
00216       (*b64)[jj++] = B64_EOL2 ;
00217    }
00218 
00219    *b64  = (byte *) realloc( *b64 , sizeof(byte)*jj ) ;
00220    *nb64 = jj ;
00221    return ;
00222 }