什么是Base64?
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,是一种用64个字符来表示任意二进制数据的方法。常用于在URL、Cookie、网页中传输少量二进制数据
用记事本打开exe
、jpg
、pdf
这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的文本处理软件能处理二进制数据,就需要一个二进制到字符串的转换方法。Base64是一种最常见的二进制编码方法
Base64的64个字符
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Base64的实现方法
对二进制数据进行处理,每3个字节一组,一共是3x8=24
bit,划为4组,每组正好6个bit:
得到4个数字(n1,n2,n3,n4)作为索引,然后查表,获得相应的4个字符,就是编码后的字符串.
例子如下:(把3字节的二进制数据编码为4字节的文本数据,长度增加33%)
3*8=4*6
内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机是8位8位的存数 6不够,自动就补两个高位0了
所有有了 高位补0
科学计算器输入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z
编解码程序如下:
//进行base64编码
//bindata:进行编码的图片数据
//base64:转换后的base64编码
//binlength:图片大小
char * base64_encode( u8 * bindata, char * base64, u32 binlength )
{
u32 i, j;
u8 current;
for ( i = 0, j = 0 ; i < binlength ; i += 3 )
{
current = (bindata[i] >> 2) ;
current &= (u8)0x3F;
base64[j++] = base64char[(int)current];
current = ( (u8)(bindata[i] << 4 ) ) & ( (u8)0x30 ) ;
if ( i + 1 >= binlength )
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
base64[j++] = '=';
break;
}
current |= ( (u8)(bindata[i+1] >> 4) ) & ( (u8) 0x0F );
base64[j++] = base64char[(int)current];
current = ( (u8)(bindata[i+1] << 2) ) & ( (u8)0x3C ) ;
if ( i + 2 >= binlength )
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
break;
}
current |= ( (u8)(bindata[i+2] >> 6) ) & ( (u8) 0x03 );
base64[j++] = base64char[(int)current];
current = ( (u8)bindata[i+2] ) & ( (u8)0x3F ) ;
base64[j++] = base64char[(int)current];
}
base64[j] = '\0';
return base64;
}
//解码base64
//base64:base64编码
//bindata:图片数据
int base64_decode( const char * base64, u8 * bindata )
{
u32 i, j;
u8 k;
u8 temp[4];
for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )
{
memset( temp, 0xFF, sizeof(temp) );
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i] )
temp[0]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+1] )
temp[1]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+2] )
temp[2]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+3] )
temp[3]= k;
}
bindata[j++] = ((u8)(((u8)(temp[0] << 2))&0xFC)) |
((u8)((u8)(temp[1]>>4)&0x03));
if ( base64[i+2] == '=' )
break;
bindata[j++] = ((u8)(((u8)(temp[1] << 4))&0xF0)) |
((u8)((u8)(temp[2]>>2)&0x0F));
if ( base64[i+3] == '=' )
break;
bindata[j++] = ((u8)(((u8)(temp[2] << 6))&0xF0)) |
((u8)(temp[3]&0x3F));
}
return j;
}
STM32对图片进行base64编码例子如下:
//图片编码函数,jpg,bmp格式都可以转换
//path:图片路径
//注意,当图片过大,采用外部SARMEX分配内存,图片较小的话可采用内部SARMIN分配内存
void pic_to_base64(const TCHAR* path)
{
u8 res=0; //返回值
UINT br;
FIL *fp = NULL; //图片指针
u32 size=0; //图片大小
u8 *picbuffer; //图片缓冲区
char *base64buffer; //base64编码缓冲区
fp=(FIL*)pic_memalloc(sizeof(FIL));
if(fp==NULL) printf("fp malloc err\n"); //申请内存失败
res=f_open(fp,path,FA_READ); //打开图片
if (res == FR_OK)
{
printf("picture open ok\n");
}
//获取图片大小
size = f_size(fp);
printf("picture size=%d\r\n",size);
//分配内存存储整个图片
picbuffer = (u8 *)mymalloc(SRAMEX,(size/4+1)*4);
if (NULL == picbuffer)
{
printf("memory1 malloc error\n");
}
//将图片拷贝到buffer
res = f_read(fp,picbuffer, size,&br);
if (res)
{
printf("pic reading error\n");
}
f_close(fp);
//分配内存空间
base64buffer = (char *)mymalloc(SRAMEX,(size/4+1)*4);
if (NULL == base64buffer)
{
printf("memory2 malloc error\n");
}
//进行base64编码
base64_encode(picbuffer, base64buffer, size);
printf("base64:%s\n", base64buffer);
pic_memfree(fp);
myfree(SRAMEX,picbuffer);
myfree(SRAMEX,base64buffer);
}