最近研究一下編碼問題,base64編碼在項目中也是經常用到的。下面簡單介紹一下base64編碼。base64相當於64進制,它是由26個大寫字母,26個小寫字母和0-9、+ 、/的字符組成,其中A代表0, a代表26,0代表52,/代表63.base64編碼的原理:將3字節轉成4個字符3個字節 = 24bits ,將24個bits分爲4組,每組6bits,將每組用一個64進制的字符表示。base64不是加密算法,只是一種數據轉換算法。與十六進制相比,base64編碼長度較短。但是其缺點是不直觀,輸出的字符存在特殊符號。
下面用代碼實現base64編碼:
#include <stdio.h>
char base64_table[64];//64進制查詢表
char revers_table[128];//反向查詢表
void initBase64_table()
{
int i;
for (i = 0; i < 26; i++) base64_table[i] = 'A' + i;
for (i = 0; i < 26; i++) base64_table[i + 26] = 'a' + i;
for (i = 0; i < 10; i++) base64_table[i + 52] = '0' + i;
base64_table[62] = '+';
base64_table[63] = '/';
//初始化反向查詢表
for (i = 0; i < 128; i++) revers_table[i] = 0;
for (i = 'A'; i <= 'Z'; i++) revers_table[i] = i - 'A';
for (i = 'a'; i <= 'z'; i++) revers_table[i] = i - 'a' + 26;
for (i = '0'; i <= '9'; i++) revers_table[i] = i - '0' + 52;
revers_table['+'] = 62;
revers_table['/'] = 63;
revers_table['='] = 0;
}
int EncodeSize(int data_size)
{
int groups = data_size / 3;
if (data_size % 3)
groups += 1;
return groups * 4 + 1;
}
//剛好三個字節時
void Encode(const unsigned char* data , char* AdBase64str)
{
//取高6位
unsigned char p0 = (data[0] >> 2);
//data[0]的低2位,data[1]的高4位
unsigned char p1 = ((data[0] & 0x03) << 4) + (data[1] >> 4);
//data[1]低4位,data[2]高3位
unsigned char p2 = ((data[1] & 0x0f) << 2) + (data[2] >> 6);
//data[2]低4位
unsigned char p3 = data[2] & 0x3f;
AdBase64str[0] = base64_table[p0];
AdBase64str[1] = base64_table[p1];
AdBase64str[2] = base64_table[p2];
AdBase64str[3] = base64_table[p3];
}
//剛好是三個字節時的編碼
void Decode(unsigned char* data , const char* base64str)
{
unsigned char p0, p1, p2, p3;
p0 = revers_table[base64str[0]];
p1 = revers_table[base64str[1]];
p2 = revers_table[base64str[2]];
p3 = revers_table[base64str[3]];
data[0] = (p0 << 2) + (p1 >> 4);
data[1] = (p1 << 4) + (p2 >> 2);
data[2] = (p2 << 6) + p3;
}
//解碼需要的長度
int Decode_size(int str_size)
{
int groups = str_size / 4;
if (str_size % 4) return -1;//字符長度不是4的整數倍
return groups * 3;
}
//通用的編碼
int Encode(const unsigned char* data, int data_size, char* base64str)
{
int groups = data_size / 3;//整除組
int remain = data_size % 3;//剩下的
const unsigned char* inbuf = data;
char* outbuf = base64str;
//處理整除部分
for (int i = 0; i < groups; i++)
{
Encode(inbuf, outbuf);
inbuf += 3;
outbuf += 4;
}
//處理剩餘的部分
if (remain == 1)
{
Encode(inbuf, outbuf);
groups += 1;
outbuf[2] = outbuf[3] = '=';//加個等號
}
if (remain == 2)
{
unsigned char t[3] = { inbuf[0], inbuf[1], 0 };
Encode(inbuf, outbuf);
groups += 1;
outbuf[3] = '=';
}
int str_size = groups * 4;
//添加結束符
base64str[str_size] = 0;
return str_size;
}
//通用解析
int Decode(unsigned char* data , const char* base64str , int str_size)
{
int groups = str_size / 4;//整除的
const char* inbuf = base64str;
unsigned char* outbuf = data;
//處理整除的部分
for (int i = 0; i < groups; i++)
{
Decode(outbuf, inbuf);
inbuf += 4;
outbuf += 3;
}
int data_size = groups * 3;
outbuf -= data_size;
//末尾2個等號
if (base64str[str_size - 1] == '=' && base64str[str_size - 2] == '=')
{
data_size -= 2;
}
if (base64str[str_size - 1] == '=' && base64str[str_size - 2] != '=')
{
data_size -= 1;
}
outbuf[data_size] = 0;
return data_size;
}
int main()
{
initBase64_table();
unsigned char data[] = { 0x4D, 0x5A, 0x90 , 0x6A , 0x7A};
char base64Str[128];
int n = Encode(data, 5 , base64Str);
char* base64 = "TVqQas==";
unsigned char data1[128];
int n1 = Decode(data1, base64 , 8);
return 0;
}