base64.c

Go to the documentation of this file.
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 //  fprintf(stderr,"base64=%.*s >> %d\n",ptr-out,out,ptr-out);
00336     //*ptr = 0;                 
00337     dst.len = ptr-dst.s;
00338     return dst;
00339 }

Generated on Thu Oct 23 04:14:37 2008 for Open IMS Core CSCFs by  doxygen 1.5.2