Base64是一种编码算法,可用于在HTTP环境下传递较长的标识信息。其将8位数据转换成6位数据的功能据说主要是用在邮件传输中。今天在工作中用到了这个编码,所以在这里将自己的理解记录下来。
一、Base64编码规则
Base64的编码规则很简单,就是将8bit数据,转换成6bit的有效数据,然后高位补两个0即可,下边来看一个例子:
例1
(1)现在有一个字符串:
“123”
(2)其二进制便是为3*8=24bit:
00110001, 00110010, 00110011
(3)要转换成Base64,则将这24位数据按6位一组编排,则刚好分成4组:
001100,010011,001000,110011
(4)再在每组的高两位补两个0,组成4组8bit数据:
00001100,00010011,00001000,00110011
(5)每组对应10进制数是:
12, 19, 8, 51
(6)我们对照该下边的编码表可以得到4个字符组成的字符串:
(7)编码出的Base64字符串:”MTIz”
看了上边的例子是不是觉得Base64编码很简单,但是你发现没有,上边我们编码的是3个字节的字符串,3*8 = 4*6,就是说刚好可以编码成4个字符。那如果我们使用的是“1”和“12”分别进行编码,不就会有剩下的2bit和4bit不能编码吗。那么接下来,我们就来详细的讨论一下关于余下的位的问题:
例2
(1)需要编码的字符串:
“1”
(2)二进制形式:
00110001
(3)每6bit一组,剩下的不足6bit的一组
001100, 01
(4)高位补上两个0:
00001100, 0001
(5)最后一组不足8位的右边补0,使之变成8位数据:
00001100, 00010000
(6)对应10进制数据:
12, 16
(7)对照编码表得到的字符串:
“MQ”
(8)由于刚才最后一组右边多补齐了4个0,则每两个0加一个‘=’号,最后得到
的字符串如下:
“MQ==”
(9)同理字符串“12”编码后的字符串为:
“MTI=”
二、Base64编码/解码C代码
附上今天刚测试过的C代码,其中ecode(char*src, char dst[])为编码函数,第二个参数是一个数组,需要向里边写入数据;相应的decode(char* src, char dst[])为解码函数。由于代码比较简单,具体代码分析就留给读者了。
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void biz_base64_encode(const char *src,char *dst)
{
int i=0;
char *p=dst;
intd=strlen(src)-3;
for(i=0;i<=d;i+=3)
{
*p++=Base64[((*(src+i))>>2)&0x3f];
*p++=Base64[(((*(src+i))&0x3)<<4)+((*(src+i+1))>>4)];
*p++=Base64[((*(src+i+1)&0xf)<<2)+((*(src+i+2))>>6)];
*p++=Base64[(*(src+i+2))&0x3f];
}
if((strlen(src)-i)==1)
{
*p++=Base64[((*(src+i))>>2)&0x3f];
*p++=Base64[((*(src+i))&0x3)<<4];
*p++='=';
*p++='=';
}
if((strlen(src)-i)==2)
{
*p++=Base64[((*(src+i))>>2)&0x3f];
*p++=Base64[(((*(src+i))&0x3)<<4)+((*(src+i+1))>>4)];
*p++=Base64[((*(src+i+1)&0xf)<<2)];
*p++='=';
}
*p='\0';
}
int base64_decode(char *src,char *dst)
{
char*q=malloc(strlen(src)+1);
char *p=dst;
char *temp=q;
char *s=src;
intlen=strlen(src),i;
memset(q,0,strlen(src)+1);
while(*s)
{
if(*s>='A'&&*s<='Z') *temp=*s-'A';
elseif(*s>='a'&&*s<='z') *temp=*s-'a'+26;
elseif(*s>='0'&&*s<='9') *temp=*s-'0'+52;
else if(*s=='+')*temp=62;
elseif(*s=='/') *temp=63;
elseif(*s=='=') *temp=0xff;
else
{
printf("\n%c:Not a valid base64 string\n",*s);
return-1;
}
++s;
++temp;
}
for(i=0;i<len-4;i+=4)
{
*p++=(*(q+i)<<2)+(*(q+i+1)>>4);
*p++=(*(q+i+1)<<4)+(*(q+i+2)>>2);
*p++=(*(q+i+2)<<6)+(*(q+i+3));
}
if(*(q+i+3) !=0xff)
{
*p++=(*(q+i)<<2)+(*(q+i+1)>>4);
*p++=(*(q+i+1)<<4)+(*(q+i+2)>>2);
*p++=(*(q+i+2)<<6)+*(q+i+3);
}
elseif(*(q+i+2) != 0xff)
{
*p++=(*(q+i)<<2)+(*(q+i+1)>>4);
*p++=(*(q+i+1)<<4)+(*(q+i+2)>>2);
*p++=(*(q+i+2)<<6);
}
elseif(*(q+i+1) != 0xff)
{
*p++=(*(q+i)<<2)+(*(q+i+1)>>4);
*p++=(*(q+i+1)<<4);
}
else
{
printf("Not a valid base64 string\n");
exit(0);
}
*p=0;
free(q);
return 0;
}