二进制转文本方案

作者: 夏日里的故事 | 来源:发表于2018-01-21 01:13 被阅读449次

    概述


    在开发当中,会经常遇到二进制数据转文本的需求,常见的应用场景如下:

    • 需要打印的时候

    例如打印到屏幕,在调试器、数据包分析等场合经常会遇到

    • 跨应用交互

    例如需要在两个无关联的应用之间交互数据,诸如两个应用之间复制、粘贴一些剪贴板、控件无法表达的数据

    • 传输协议不支持

    一些传输协议不支持二进制直接传输,只好转换后再进行传输

    转换方案

    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

    相关文章

      网友评论

        本文标题:二进制转文本方案

        本文链接:https://www.haomeiwen.com/subject/awjxaxtx.html