最近研究一下编码问题,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;
}