什麼是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);
}