Base64编码简介
缘起
想把protobuf的message按字节数组输出,以前写到hbase里,很自然;但是现在需要写到hdfs上,突然就没法子了。google大法,发现有个base64的东西,问题一下迎刃而解。
- 输出字节数组:转成base64 string;
- 读取字节数组:从base64 string反解回来。
Dependencies
commons-codec,这个包比较好用,一堆thread safe的静态函数,就能搞定问题。12345<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version></dependency>
原理
- 每3个8位二进制码位一组,转换为4个6位二进制码为一组(不足6位时地位补0)。3个8位二进制码和4个6位二进制码长度都是24位。
- 对获得的4个6位二进制码补位,每个6位二进制码添加两位高位0,组成4个8位二进制码。
- 将获得的4个8位二进制码转换为4个十进制码。
- 将获得的十进制码转换为Base64字符表中对应的字符,对照表。
另外,当原文的二进制码长度不是24的倍数,最终转换为十进制时也不足4项,这时就需要用=补位。
RFC2045还规定每行位76个字符,每行末尾需添加一个回车换行符(\r\n),即便是最后一行不够76个字符,也要加换行符。
commons-codec 三种模式
- 标准的RFC2045,每76个字符加上(\r\n),有补位等号,即chunked的模式
- 有补位等号,但是不加(\r\n),即url unsafe模式
- Url Base64,也就是将“+”和“\”换成了“-”和“_”符号,且不适用补位,即url safe模式
例子
|
|
- 分析首三字母 hel –> aGVs
二进制表示:
h = 01101000
e = 01100101
l = 01101100
c1 | c2 | c3 | c4 |
---|---|---|---|
011010 | 000110 | 010101 | 101100 |
26 | 6 | 21 | 44 |
a | G | V | s |
- 分析末尾两个字母 4!
根据规则,3个原始byte一组转换,最后剩余的byte组成一组,
二进制表示:
4 = 00110100
! = 00100001
每6个bit构成base64编码的一个字母,剩余4个bit后面需补充2个0bit,构成第三个字母
c1 | c2 | c3 |
---|---|---|
001101 | 000010 | 000100 |
13 | 2 | 4 |
N | C | E |
因为只有NCE三个字母,所以需要一个部位等号,凑足4个字母,如果按照标准的base64编码,还需要加上 \r\n
结合protobuf的应用
|
|
利弊
优点
- 7 Bit ASCII characters are safe for transmission over the network and between different systems
- SMPT protocol for emails supports only 7 Bit ASCII Characters. Base64 is the commonly used technique to send binary files as attachments in emails.
缺点
- Base64 encoding bloats the size of the original binary stream by 33 percent
- Encoding/Decoding process consumes resources and can cause performance problems
reference: