数据的编码(2)之BASE64编码

本文深入探讨了Base64编码的原理与应用,包括64进制字符集、编码算法及其实现。通过对比十六进制,展示了Base64编码在项目中的优势。并提供了C语言实现的编码与解码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndyWei147

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值