概述
在开发当中,会经常遇到二进制数据转文本的需求,常见的应用场景如下:
- 需要打印的时候
例如打印到屏幕,在调试器、数据包分析等场合经常会遇到
- 跨应用交互
例如需要在两个无关联的应用之间交互数据,诸如两个应用之间复制、粘贴一些剪贴板、控件无法表达的数据
- 传输协议不支持
一些传输协议不支持二进制直接传输,只好转换后再进行传输
转换方案
Base64
这个方案,可以说是无人不知,无人不晓了,其基本原理就是使用:大小写字母、10个阿拉伯数字(0~9)以及"+"和"/"总共64个可打印字符来转换、表达任意二进制数据,也因此叫Base64。
通常Base64用于程序与程序之间交换数据,而不是给人类识别的,有时候,转换后,可能比原始数据更不可识别(例如将一段文字进行Base64转换),因此有人还称之为:“加密”。
在Java中,实现Base64有很多库可以支持,如果是:Java 1.6/1.7,可以使用:apache common-codec, 如果是Java 1.8,标准库里面就有了:java.util.Base64
如果是Android,可以直接使用:android.util.base64
Base16
Base16也就是常说的“HEX字符串”,编码非常简单,按照4bit为一组,0对应可打印字符的0,1对应可以打印字符的1,依次类推。
Base16便于人类识别和分析,通常用于数据分析。
在调试器中,查看内存值、内存地址,通常以这种形式的输出;很多抓包工具以及数据分析工具默认就是这种形式来表达数据;一些嵌入式烧录工具的输入、输出文件,也是这种格式,便于工程师使用文本工具分析和修改。
大部分语言的标准库,都提供当个字节的HEX格式化输出,因此该编码转换不需要特殊的库。
Base58
如果熟悉比特币或者区块链的读者,相信对Base58非常熟悉了,早期比特币钱包地址希望打印到屏幕,或者手抄到纸上,为了避免:O(大写字母)、0(数字的零)、l(小写字母的L)、I(大写字母的I)、'+'和'/',对人类的视觉以及程序的干扰(+和/有时候会干扰程序的双机选择),毕竟他们在有些字体下面,辨别度实在太低了。因此在Base64的基础上,剔除了上述字母进行编码。
除了钱包地址,短URL采用这种编码也是挺实在的。
需要注意的是:Base58并没有具体标准,而Base64是一项RFC标准。不同的应用,编码的字母表的可能不同。
下面是不同的应用,使用的字母表:
应用 | 字母表 |
---|---|
比特币地址 | 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz |
ripple币 | rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz |
Flickr短URL | 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ |
Ascii85/Base85
这种编码比较少人知道。二进制转文本,转换后数据大小必然比原始的大,对于Base64会增大1/3左右的体积,而Ascii85只增大1/4体积,对于一些数据量大的场合,这种编码方案就显得实在了。在Adobe PostScript、ZeroMQ、Git等都有应用。
早期他们是没有标准的,后来,在Robert Elz
建议,使用Base85来编码IPV6地址,因此,成为了一项RFC标准,对于RFC标准版本,也就是Base85,使用:0–9, A–Z, a–z, 以及23个字符: !#$%&()*+-;<=>?@^_`{|}~ 来编码二进制数据。
Quoted-Printable / QP encoding
如果做过邮件协议开发,相信不会陌生,它是MIME的一种实现方式(还有Base64),主要解决支持非ASCII字符、二进制格式附件等多种格式的邮件消息。
编码规则也很简单,任何一个8bit字节,都可以编码成:=加十六进制的字符值(也就是之前提到的Base16)。例如:空格(ASCII值为20),就表达成:=20;对于可打印的ASCII值,十进制值的范围为33到126,直接显示;TAB和空格,如果不在行尾,可以直接显示,否则需要转换=编码;CR和LF也是通常处理,实际上,为了省事,直接将TAB、空格、CR、LF也一起转换编码。
例如:this is a 简书文章(UTF-8字符串)
可以编码成:
this=20is=20a=20=E7=AE=80=E4=B9=A6=E6=96=87=E7=AB=A0
其他
其他方案还有挺多,例如:UUencode、Base122、Base36等等,详情可以阅读维基百科:https://en.wikipedia.org/wiki/Binary-to-text_encoding
网友评论