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 }