【编码】Base64 编码

一、简介:

Base64:是网络上最常见的用于传输8Bit字节码的编码方式之一,是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。

Base64 编码:包括小写字母a-z、大写字母A-Z、数字0-9、符号"+“、”/"一共64个字符的字符集,(任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做base64编码。

Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

Base64被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。

二、编码规则

  1. 把3个字节变成4个字节( 3 x 8 = 4 x 6 = 24 , 把6Bit再添两位高位0,组成四个8Bit的字节 )
  2. 每76个字符加一个换行符
  3. 最后的结束符也要处理

原始base64编码 是使用原始Base64表的字符顺序的编码, 私有Base64编码 是使用了私有Base64表(改变了原始表字符顺序的编码)
 Base 64 (摘自RFC2045)

例如:

转换前: 11111111, 11111111, 11111111
转换后: 00111111, 00111111, 00111111, 00111111

转换前: 10101101, 10111010, 01110110
转换后: 00101011, 00011011, 00101001, 00110110
转换后十进制: 43 27 41 54
转换后对应码表中的值: r b p 2

三、实现

1. 基于 C 实现 原始 Base64

static const char base64_chars[] = 
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

char * base64_encode(const unsigned char * data, size_t dataLen) 
{
    size_t i=0, j=0;
    // 计算输出长度,编码长度需被 4 整除 
    size_t outputLen = 4 * (dataLen / 3);
    if(dataLen %3 > 0)
    {
        outputLen += 4;
    }
    // 申请 堆上空间存储 输出编码
    char * encodeData = (char *)malloc(outputLen);
    if (NULL == encodeData) 
    {
        return NULL;
    }
    for(i=0, j=0; i<dataLen; )
    {
        // 组合成 32 位
        uint32_t triple = 0x0000;
        // Base64 是将 3个8位 拆分为 4个8位
        // 特殊情况之一:如果输入 ! 
        // first = 0010 0001  dataLen = 1 ==> second = 0000 0000 third = 0000 0000  
        // triple = 0010 0001 0000 0000 0000 0000
        // 0000 1000 | 0001 0000 | 0000 0000 | 0000 0000
        uint8_t first = i < dataLen ? data[i++] : ~0xff;
        uint8_t second = i < dataLen ? data[i++] : ~0xff;
        uint8_t third = i < dataLen ? data[i++] : ~0xff;
        triple = ((first <<16 ) + (second << 8) + (third));
        // 位操作 获取 data 
        // 0x3f - 0011 1111
        // 如果输入 ! triple = 0010 0001 0000 0000 0000 0000 => 00 1000 0100 0000 0000 
        encodeData[j++] = base64_chars[(triple >> (3 * 6)) & 0x3F];
        encodeData[j++] = base64_chars[(triple >> (2 * 6)) & 0x3F];       
        encodeData[j++] = base64_chars[(triple >> (1 * 6)) & 0x3F];
        encodeData[j++] = base64_chars[(triple >> (0 * 6)) & 0x3F];
    }
    for(size_t i=0; i<(3-dataLen%3); i++) 
    {
        encodeData[outputLen -1 -i] = '=';
    }
    return encodeData;
}

2. 基于 C++ 实现 原始 Base64

// 原始Base64表
std::string kBase64CodeTable =
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// std::string const& raw 原始数据
// std::string* out 编码后数据
int Base64Encode(std::string const& raw, std::string* out) 
{
	// 1.
	// 获取字符串长度
	int len = raw.size();
	for (int i = 0; i < len; i += 3) 
	{
		// 2.
		// 循环遍历原始字符串,每次处理3个字符
		// 组成第一个八位  0xFC - 1111 1100 
		out->push_back(kBase64CodeTable[(raw[i] & 0xFC)>>2]);
		
		if (i+1 >= len) 
		{ 
			// 原始数据只剩一个字符 01-> 0001 0000 
			// 0x03 - 0000 0011
			out->push_back(kBase64CodeTable[(raw[i] & 0x03)<<4]);
            break;
		}
		// 0x03 - 0000 0011   0xf0 - 1111 0000
		out->push_back(kBase64CodeTable[(raw[i] & 0x03)<<4|(raw[i+1] & 0xF0)>>4]);
		
		//	组成第三个八位
		if (i+2 >= len) 
		{
			// 原始数据 只剩两个字符
			 out->push_back(kBase64CodeTable[(raw[i+1] & 0x0F)<<2]);
             break;
		}
		// 原始数据 足够三个字符
		// 0x0f - 0000 1111  0xb0 - 1100 0000
		out->push_back(kBase64CodeTable[(raw[i+1] & 0x0F)<<2 |(raw[i+2] & 0xC0)>>6]);
		// 组成第四个八位
		// 0x3f - 0011 1111
		out->push_back(kBase64CodeTable[raw[i+2] & 0x3F]);
	}
	   	len = out->size();
  		if (len % 4 != 0) 
        {
            out->append(std::string(4-len%4, '='));
        }
        return 0;
}
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

育碧不配有妈妈、

创作不易,自愿投币

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

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

打赏作者

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

抵扣说明:

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

余额充值