百科对base64的简述:
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char _Base[]={"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="};
static union
{
struct
{
unsigned long a:6;
unsigned long b:6;
unsigned long c:6;
unsigned long d:6;
}Sdata;
unsigned char c[3];
}Udata;
char * Encbase64(char * orgdata,unsigned long orglen,unsigned long *newlen);
char * Decbase64(char * orgdata,unsigned long orglen);
int main(int argc,char *agv[])
{
unsigned long nlen;
printf("%s\n",Encbase64("i love travel",strlen("i love travel"),&nlen));
printf("%s\n",Decbase64("aSBsb3ZlIHRyYXZlbA==",strlen("aSBsb3ZlIHRyYXZlbA==")));
return 0;
}
char * Encbase64(char * orgdata,unsigned long orglen,unsigned long *newlen)
{
char *p=NULL,*ret=NULL;
int tlen=0;
if (orgdata==NULL|| orglen==0)
return NULL ;
tlen=orglen/3;
if(tlen%3!=0) tlen++;
tlen=tlen*4;
*newlen=tlen;
if ((ret=(char *)malloc(tlen+1))==NULL)
return NULL;
memset(ret,0,tlen+1);
p=orgdata;tlen=orglen;
int i=0,j=0;
while(tlen>0)
{
Udata.c[0]=Udata.c[1]=Udata.c[2]=0;
for (i=0;i<3;i++)
{
if (tlen<1) break;
Udata.c[i]=(char)*p;
tlen--;
p++;
}
if (i==0) break;
switch (i)
{
case 1:
/*ret[j++]=_Base[Udata.Sdata.d];
ret[j++]=_Base[Udata.Sdata.c];
ret[j++]=_Base[64];
ret[j++]=_Base[64];*/
ret[j++]=_Base[Udata.c[0]>>2];
ret[j++]=_Base[((Udata.c[0]&0x03)<<4)|((Udata.c[1]&0xf0)>>4)];
ret[j++]=_Base[64];
ret[j++]=_Base[64];
break;
case 2:
/*ret[j++]=_Base[Udata.Sdata.d];
ret[j++]=_Base[Udata.Sdata.c];
ret[j++]=_Base[Udata.Sdata.b];
ret[j++]=_Base[64];*/
ret[j++]=_Base[Udata.c[0]>>2];
ret[j++]=_Base[((Udata.c[0]&0x03)<<4)|((Udata.c[1]&0xf0)>>4)];
ret[j++]=_Base[((Udata.c[1]&0x0f)<<2)|((Udata.c[2]&0xc0)>>6)];
ret[j++]=_Base[64];
break;
case 3:
/*ret[j++]=_Base[Udata.Sdata.d];
ret[j++]=_Base[Udata.Sdata.c];
ret[j++]=_Base[Udata.Sdata.b];
ret[j++]=_Base[Udata.Sdata.a];*/
ret[j++]=_Base[Udata.c[0]>>2];
ret[j++]=_Base[((Udata.c[0]&0x03)<<4)|((Udata.c[1]&0xf0)>>4)];
ret[j++]=_Base[((Udata.c[1]&0x0f)<<2)|((Udata.c[2]&0xc0)>>6)];
ret[j++]=_Base[Udata.c[2]&0x3f];
break;
default:
break;
}
}
ret[j]='\0';
return ret;
}
char * Decbase64(char * orgdata,unsigned long orglen)
{
char *p,*ret;
int len;
char ch[4]={0};
char *pos[4];
int offset[4];
if (orgdata==NULL || orglen==0)
{
return NULL;
}
len=orglen*3/4;
if ((ret=(char *)malloc(len+1))==NULL)
{
return NULL;
}
p=orgdata;
len=orglen;
int j=0;
while(len>0)
{
int i=0;
while(i<4)
{
if (len>0)
{
ch[i]=*p;
p++;
len--;
if ((pos[i]=(char *)strchr(_Base,ch[i]))==NULL)
{
return NULL;
}
offset[i]=pos[i]-_Base;
}
i++;
}
if (ch[0]=='='||ch[1]=='='||(ch[2]=='='&&ch[3]!='='))
{
return NULL;
}
ret[j++]=(unsigned char)(offset[0]<<2|offset[1]>>4);
ret[j++]=offset[2]==64?'\0':(unsigned char)(offset[1]<<4|offset[2]>>2);
ret[j++]=offset[3]==64?'\0':(unsigned char)((offset[2]<<6&0xc0)|offset[3]);
}
ret[j]='\0';
return ret;
}