最近工作需要将二进制保存到hive里,但是很不幸,hive不支持bit字节流的存储,尤其是不定长的字节流。怎么办呢?我们的解决方案是将二进制转成可见的字符再存储字符串。于是使用Base64进行编码。在Java中使用Base64是十分方便的,因为java8自带base64的工具包。但是我们的字节流dump过程是在c++里实现的,而c++的stl中是不会有这个东西的。怎么办?还好我们有boost,但是boost是一个比较庞大复杂的东西,对于我们这个简单的功能实在是大材小用。我不太想引入这个。于是自己造轮子吧。
Base64原理
Base64的原理的文章有很多,大家可以自己找别的文章看一下。比如这一篇就不错。简单点来说就是把原字节流每3个字节(24位)重新组合,以每6位进行重新划分,就重新得到4个值。这4个值就必定会落在[0, 2^6)的区间内。2^6 = 64。所以BASE64算法里有一个table,是64个ASCII可见字符,相当于是编码集。所以每个新得到的值从table里取自己对应的那一个字符,就算是编码了。所以编码前字节流中每3个字节,编码后会对应4个新的ASCII字符(正好也是一个字节)。所以编码后,存储就变成了之前的4/3了。(注:如果编码到最后不够3字节,那编码最后会补上‘=’,具体看这一篇)。
代码
光说不练假把式。本代码使用的是C++11规范。上代码:
#include <map>
#include <string>
char table[64] = {
'A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X',
'Y','