00001
00055 #include <sys/types.h>
00056 #include <stdio.h>
00057 #include "string.h"
00058 #include "stdlib.h"
00059 #include "base64.h"
00060
00061 #include "mod.h"
00062 #include "../../mem/mem.h"
00063
00064
00065
00067 static char hexa[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
00068
00074 str base16_encode(str src)
00075 {
00076 int i,j,x1,x2;
00077 str dst={0,0};
00078
00079 dst.len=src.len*2;
00080 dst.s=pkg_malloc(dst.len);
00081 if (!dst.s){
00082 LOG(L_ERR,"ERR:"M_NAME":bin2hexa: error allocating %d bytes\n",dst.len);
00083 dst.len = 0;
00084 return dst;
00085 }
00086 for(i=0,j=0;i<src.len;i++){
00087 x1=((unsigned char)src.s[i])/16;
00088 x2=((unsigned char)src.s[i])%16;
00089 dst.s[j++]=hexa[x1];
00090 dst.s[j++]=hexa[x2];
00091 }
00092 dst.len=j;
00093 return dst;
00094 }
00095
00097 #define HEX2VALUE(x) ((x)>='0'&&(x)<='9'?(x)-'0':((x)>='a'&&(x)<='f'?(x)-'a'+10:((x)>='A'&&(x)<='F'?(x)-'A'+10:0)))
00098
00103 str base16_decode(str src)
00104 {
00105 int i,j;
00106 unsigned char x1,x2;
00107 str dst={0,0};
00108
00109 dst.len=src.len/2;
00110 dst.s=pkg_malloc(dst.len);
00111 if (!dst.s){
00112 LOG(L_ERR,"ERR:"M_NAME":hexa2bin: error allocating %d bytes\n",dst.len);
00113 dst.len = 0;
00114 return dst;
00115 }
00116 for(i=0,j=0;j<dst.len;i+=2,j++){
00117 x1 = (unsigned char) src.s[i];
00118 x2 = (unsigned char) src.s[i+1];
00119 dst.s[j]=(unsigned char)(HEX2VALUE(x1)*16+HEX2VALUE(x2));
00120 }
00121 return dst;
00122 }
00123
00124
00125 #define PAD_CHAR '.'
00126
00133 static int base64_val(char x)\
00134 {
00135 switch(x){
00136 case PAD_CHAR: return -1;
00137 case 'A': return 0;
00138 case 'B': return 1;
00139 case 'C': return 2;
00140 case 'D': return 3;
00141 case 'E': return 4;
00142 case 'F': return 5;
00143 case 'G': return 6;
00144 case 'H': return 7;
00145 case 'I': return 8;
00146 case 'J': return 9;
00147 case 'K': return 10;
00148 case 'L': return 11;
00149 case 'M': return 12;
00150 case 'N': return 13;
00151 case 'O': return 14;
00152 case 'P': return 15;
00153 case 'Q': return 16;
00154 case 'R': return 17;
00155 case 'S': return 18;
00156 case 'T': return 19;
00157 case 'U': return 20;
00158 case 'V': return 21;
00159 case 'W': return 22;
00160 case 'X': return 23;
00161 case 'Y': return 24;
00162 case 'Z': return 25;
00163 case 'a': return 26;
00164 case 'b': return 27;
00165 case 'c': return 28;
00166 case 'd': return 29;
00167 case 'e': return 30;
00168 case 'f': return 31;
00169 case 'g': return 32;
00170 case 'h': return 33;
00171 case 'i': return 34;
00172 case 'j': return 35;
00173 case 'k': return 36;
00174 case 'l': return 37;
00175 case 'm': return 38;
00176 case 'n': return 39;
00177 case 'o': return 40;
00178 case 'p': return 41;
00179 case 'q': return 42;
00180 case 'r': return 43;
00181 case 's': return 44;
00182 case 't': return 45;
00183 case 'u': return 46;
00184 case 'v': return 47;
00185 case 'w': return 48;
00186 case 'x': return 49;
00187 case 'y': return 50;
00188 case 'z': return 51;
00189 case '0': return 52;
00190 case '1': return 53;
00191 case '2': return 54;
00192 case '3': return 55;
00193 case '4': return 56;
00194 case '5': return 57;
00195 case '6': return 58;
00196 case '7': return 59;
00197 case '8': return 60;
00198 case '9': return 61;
00199 case '+': return 62;
00200 case '-': return 63;
00201 }
00202 return 0;
00203 }
00204
00212 str base64_decode( str src)
00213 {
00214 int i,j,x1,x2,x3,x4;
00215 str dst = {0,0};
00216 dst.len = ( src.len * 3/4 ) + 8 ;
00217 dst.s = (char *)pkg_malloc( dst.len );
00218 if (!dst.s){
00219 LOG(L_ERR,"ERR:"M_NAME":base64_decode: error allocating %d bytes\n",dst.len);
00220 dst.len = 0;
00221 return dst;
00222 }
00223
00224 for(i=0,j=0;i+3<src.len;i+=4){
00225 x1=base64_val(src.s[i]);
00226 x2=base64_val(src.s[i+1]);
00227 x3=base64_val(src.s[i+2]);
00228 x4=base64_val(src.s[i+3]);
00229 dst.s[j++]=(x1<<2) | ((x2 & 0x30)>>4);
00230 if (x3!=-1) dst.s[j++]=((x2 & 0x0F)<<4) | ((x3 & 0x3C)>>2);
00231 if (x4!=-1) dst.s[j++]=((x3 & 0x03)<<6) | (x4 & 0x3F);
00232 }
00233 if (i<src.len) {
00234 x1 = base64_val(src.s[i]);
00235 if (i+1<src.len)
00236 x2=base64_val(src.s[i+1]);
00237 else
00238 x2=-1;
00239 if (i+2<src.len)
00240 x3=base64_val(src.s[i+2]);
00241 else
00242 x3=-1;
00243 if(i+3<src.len)
00244 x4=base64_val(src.s[i+3]);
00245 else x4=-1;
00246 if (x2!=-1) {
00247 dst.s[j++]=(x1<<2) | ((x2 & 0x30)>>4);
00248 if (x3==-1) {
00249 dst.s[j++]=((x2 & 0x0F)<<4) | ((x3 & 0x3C)>>2);
00250 if (x4==-1) {
00251 dst.s[j++]=((x3 & 0x03)<<6) | (x4 & 0x3F);
00252 }
00253 }
00254 }
00255
00256 }
00257 dst.len=j;
00258 return dst;
00259 }
00260
00262 char base64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
00263
00272 str base64_encode( str src )
00273 {
00274 int i,k;
00275 int triplets,rest;
00276 str dst={0,0};
00277 char *ptr;
00278
00279 triplets = src.len/3;
00280 rest = src.len%3;
00281 dst.len = ( triplets * 4 ) + 8 ;
00282 dst.s = (char *)pkg_malloc( dst.len );
00283 if (!dst.s){
00284 LOG(L_ERR,"ERR:"M_NAME":base64_encode: error allocating %d bytes\n",dst.len);
00285 dst.len = 0;
00286 return dst;
00287 }
00288
00289
00290 ptr = dst.s;
00291 for(i=0;i<triplets*3;i+=3){
00292 k = (((unsigned char) src.s[i])&0xFC)>>2;
00293 *ptr=base64[k];ptr++;
00294
00295 k = (((unsigned char) src.s[i])&0x03)<<4;
00296 k |=(((unsigned char) src.s[i+1])&0xF0)>>4;
00297 *ptr=base64[k];ptr++;
00298
00299 k = (((unsigned char) src.s[i+1])&0x0F)<<2;
00300 k |=(((unsigned char) src.s[i+2])&0xC0)>>6;
00301 *ptr=base64[k];ptr++;
00302
00303 k = (((unsigned char) src.s[i+2])&0x3F);
00304 *ptr=base64[k];ptr++;
00305 }
00306 i=triplets*3;
00307 switch(rest){
00308 case 0:
00309 break;
00310 case 1:
00311 k = (((unsigned char) src.s[i])&0xFC)>>2;
00312 *ptr=base64[k];ptr++;
00313
00314 k = (((unsigned char) src.s[i])&0x03)<<4;
00315 *ptr=base64[k];ptr++;
00316
00317 *ptr=PAD_CHAR;ptr++;
00318
00319 *ptr=PAD_CHAR;ptr++;
00320 break;
00321 case 2:
00322 k = (((unsigned char) src.s[i])&0xFC)>>2;
00323 *ptr=base64[k];ptr++;
00324
00325 k = (((unsigned char) src.s[i])&0x03)<<4;
00326 k |=(((unsigned char) src.s[i+1])&0xF0)>>4;
00327 *ptr=base64[k];ptr++;
00328
00329 k = (((unsigned char) src.s[i+1])&0x0F)<<2;
00330 *ptr=base64[k];ptr++;
00331
00332 *ptr=PAD_CHAR;ptr++;
00333 break;
00334 }
00335
00336
00337 dst.len = ptr-dst.s;
00338 return dst;
00339 }