www.pudn.com > uri_enc_base64_enc.rar > uribase64_codec.c


//#include  
#include  
#include 	 
#include 	 
		 
// base64 tables	 
static char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
 
#define CHAR64(c)  (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) 
 
char * base64_encode(const unsigned char *value, int vlen);	 
unsigned char * base64_decode(const char *value, int *rlen); 
	 
static signed char index_64[128] = {	 
	    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,	 
	    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,	 
	    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,	 
	    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,	 
	    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,	 
	    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,	 
	    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,	 
	    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1	 
} ; 
	 
char *base64_encode(const unsigned char *value, int vlen) { 
	unsigned char oval = 0 ; 	 
        char *result = (char *)malloc((vlen * 4) / 3 + 5) ;	 
        char *out = result;	 
	while (vlen >= 3) {	 
        	*out++ = basis_64[value[0] >> 2];	 
        	*out++ = basis_64[((value[0] << 4) & 0x30) | (value[1] >> 4)];	 
        	*out++ = basis_64[((value[1] << 2) & 0x3C) | (value[2] >> 6)];	 
        	*out++ = basis_64[value[2] & 0x3F];	 
        	value += 3;	 
       		vlen -= 3;	 
    	} 
	if (vlen > 0) {	 
	        *out++ = basis_64[value[0] >> 2];	 
	        oval = (value[0] << 4) & 0x30 ;	 
	        if (vlen > 1) oval |= value[1] >> 4;	 
	        *out++ = basis_64[oval];	 
	        *out++ = (vlen < 2) ? '=' : basis_64[(value[1] << 2) & 0x3C];	 
	        *out++ = '=';	 
	}	 
	*out = '\0';		 
	return result;	 
}	 
 
unsigned char *base64_decode(const char *value, int *rlen)	 
{		 
	int c1, c2, c3, c4;	        	 
        int vlen = strlen(value);	 
	unsigned char *result =(unsigned char *)malloc((vlen * 3) / 4 + 1);	 
	unsigned char *out = result;	 
	 
	*rlen = 0; 
	 
	while (1) {	 
		if (value[0]==0) { 
			*out = '\0' ;  
			return result;	 
		} 
	        c1 = value[0];	 
                if (CHAR64(c1) == -1) goto base64_decode_error; 
	             c2 = value[1];	 
	             if (CHAR64(c2) == -1) goto base64_decode_error; 
	             c3 = value[2];	 
	             if ((c3 != '=') && (CHAR64(c3) == -1)) goto base64_decode_error; 
	             c4 = value[3];	 
	             if ((c4 != '=') && (CHAR64(c4) == -1)) goto base64_decode_error;	 
                     value += 4;	 
	             *out++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);	 
	             *rlen += 1;	 
	             if (c3 != '=') {	 
	             	*out++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);	 
	                *rlen += 1;	 
	                if (c4 != '=') {	 
	                	*out++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);	 
	                        *rlen += 1;	 
	                } 
	             }	 
	}	 
	base64_decode_error:	 
	        *result = 0;	 
	        *rlen = 0;	 
	        return result;	 
} 
 
const char HEX2DEC[256] =  
{ 
    /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */ 
    /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1, 
     
    /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
     
    /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
     
    /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 
    /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1 
}; 
     
void uri_decode(const char * psrc, const int len, char * pres, int * plen) 
{ 
    // Note from RFC1630:  "Sequences which start with a percent sign 
    // but are not followed by two hexadecimal characters (0-9, A-F) are reserved 
    // for future extension" 
    const int SRC_LEN = len ;  
    const unsigned char * const SRC_END = psrc + SRC_LEN ; 
    const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%'  
 
    char * const pstart = (char *)malloc(SRC_LEN) ; 
    char * pend = pstart ; 
 
    while (psrc < SRC_LAST_DEC) { 
       if (*psrc == '%') { 
            char dec1, dec2; 
            if (-1 != (dec1 = HEX2DEC[*(psrc + 1)]) 
                && -1 != (dec2 = HEX2DEC[*(psrc + 2)]))  { 
                *pend++ = (dec1 << 4) + dec2; 
                psrc += 3; 
                continue; 
            } 
        } 
        *pend++ = *psrc++; 
    } 
 
    // the last 2- chars 
    while (psrc < SRC_END) *pend++ = *psrc++; 
    *plen = (pend - pstart) ;  
    memcpy(pres, pstart, *plen) ;  
    free(pstart) ; 
} 
 
// Only alphanum is safe. 
char SAFE[256] = 
{ 
    /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */ 
    /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, 
     
    /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 
    /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, 
    /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 
    /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, 
     
    /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
     
    /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 
    /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 
}; 
 
void uri_encode(const char * psrc, const int len, char * pres, int * plen) 
{ 
     
    const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; 
    const int SRC_LEN = len ;  
    unsigned char * const pstart = (unsigned char *)malloc(SRC_LEN * 3) ; 
    unsigned char * pend = pstart; 
    const unsigned char * const SRC_END = psrc + SRC_LEN; 
    for (; psrc < SRC_END; ++psrc) { 
       if (SAFE[*psrc]) { 
	*pend++ = *psrc; 
       } else { 
            // escape this char 
            *pend++ = '%'; 
            *pend++ = DEC2HEX[*psrc >> 4]; 
            *pend++ = DEC2HEX[*psrc & 0x0F]; 
       } 
    } 
    *plen = pend - pstart ;  
    memcpy(pres, pstart, *plen) ;  
    free(pstart) ; 
} 
 
int main(int argc, char * argv[])  
{ 
  char s1[] = "http://www.google.com";  
  int len1 = strlen(s1) ;  
  char s2[100] ;  
  int len2 = 0 ;  
  char s3[100] ;  
  int len3 = 0 ;  
  char * pbase64 = NULL ;  
  int len_base64 = 0 ;  
  char * pbase64_dec = NULL ;  
  int len_base64_dec = 0 ;  
   
  memset(s2, 0, sizeof(s2)) ;  
  memset(s3, 0, sizeof(s3)) ;   
   
  printf("original : %s\n", s1) ;  
  uri_encode(s1, len1, s2, &len2) ;  
  printf("uri encode : %s\n", s2) ; 
  pbase64 = base64_encode(s2, len2) ;  
  printf("base64 encode : %s\n", pbase64) ; 
  len_base64 = strlen(pbase64) ;  
  pbase64_dec = base64_decode(pbase64, &len_base64_dec) ;  
  printf("base64 decode : %s\n", pbase64_dec) ; 
  uri_decode(pbase64_dec, len_base64_dec, s3, &len3) ;  
  printf("uri decode : %s\n", s3) ;  
  return 0 ;  
}