Base64

Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法。由于,所以每6个位元为一个单元,对应某个可打印字符。3个字节相當於24个位元,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。在Base64中的可打印字符包括字母A-Za-z数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后BinHex的版本使用不同的64字符集来代表6个二进制数字,但是不被稱為Base64。

Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME电子邮件XML的一些复杂数据。

RFC 4648 标准的 Base64 索引表

十进制二进制字符   十进制二进制字符   十进制二进制字符   十进制二进制字符
0000000A16010000Q32100000g48110000w
1000001B17010001R33100001h49110001x
2000010C18010010S34100010i50110010y
3000011D19010011T35100011j51110011z
4000100E20010100U36100100k521101000
5000101F21010101V37100101l531101011
6000110G22010110W38100110m541101102
7000111H23010111X39100111n551101113
8001000I24011000Y40101000o561110004
9001001J25011001Z41101001p571110015
10001010K26011010a42101010q581110106
11001011L27011011b43101011r591110117
12001100M28011100c44101100s601111008
13001101N29011101d45101101t611111019
14001110O30011110e46101110u62111110+
15001111P31011111f47101111v63111111/
填充=

示例

舉例來說,一段引用自托马斯·霍布斯利维坦》的文句:

Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.

經過Base64編碼之後變成:

TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=

编码「Man」的結果為TWFu,詳細原理如下:

文本 M a n
ASCII编码 77 97 110
二进制位 010011010110000101101110
索引 19 22 5 46
Base64编码 T W F u

在此例中,Base64算法将3个字节编码为4个字符。

如果要编码的字节数不能被3整除,最后会多出1个或2个字节,那么可以使用下面的方法进行处理:先使用0字节值在末尾补足,使其能够被3整除,然后再进行Base64的编码。在编码后的Base64文本后加上一个或两个=号,代表补足的字节数。也就是说,当最后剩余两个八位(待补足)字节(2个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个等号;如果最后剩余一个八位(待补足)字节(1个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等号。 参考下表:

文本(1 Byte) A
二进制位 010000010000
二进制位(補0) 010000010000留空填充留空填充
Base64编码 Q Q = =
文本(2 Byte) B C
二进制位 010000100100001100
二进制位(補0) 010000100100001100留空填充
Base64编码 Q k M =

应用

变种

base64编码对应的64个可打印字符在一些特定的程序或协议中可能不适合使用,特别是字符表第62位(+)、63位(/)和填充字符(=),因此存在一些如下的变种:

编码 编码字符 换行的处理 是否解码非编码字符
第62位 第63位 填充 分隔符 行字符数 校验和
RFC 1421:用于隐私增强电邮的Base64(已弃用) +/= 强制 CR+LF64,末尾行可少于64
RFC 2045:用于MIME的Base64 +/= 强制 CR+LF上限 76弃用
RFC 2152: 用于UTF-7的Base64 +/
RFC 3501:用于IMAP协议邮箱命名的Base64 +,
RFC 4648 §4:标准base64 +/= 可选
RFC 4648 §5:base64url(URL和文件名安全标准) -_= 可选
RFC 4880:用于OpenPGP的Radix-64 +/= 强制 CR+LF上限 76Radix-64编码24位CRC

    MIME

    MIME格式的电子邮件中,Base64可以用来将binary的字节序列数据编码ASCII字符序列构成的文本。使用时,在传输编码方式中指定Base64。使用的字符包括大小写拉丁字母各26个、数字10个、加号+和斜杠/,共64个字符,等号=用来作为填充用途。

    完整的Base64定义可见RFC 1421和RFC 2045。编码后的数据比原始数据略长,为原来的。在电子邮件中,根据RFC 822规定,每76个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%。

    转换的时候,将3字节的数据,先后放入一个24位元的缓冲区中,先来的字节占高位。数据不足3字节的话,於緩衝區中剩下的位元用0补足。每次取出6位元(因为),按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出,直到全部输入数据转换完成。

    若原数据长度不是3的倍數时且剩下1個輸入數據,則在編碼結果後加2個=;若剩下2個輸入數據,則在編碼結果後加1個=

    IRCu

    IRCu等软件所使用的P10 IRC服务器间协议中,对客户与服务器的消息类型号(client/server numerics)和二进制IP地址采用了Base64编码。消息类型号的长度固定为3字节,故可直接编码为4个字节而不需要加填充。对IP地址进行编码时,则需要在地址前添加一些0比特,使之可以编码为整数个字节。这里所用的符号集与前述MIME的也有所不同,将+/改成了[]

    UTF-7

    UTF-7是一个修改版Base64(Modified Base64)。主要是将UTF-16的数据,用Base64的方法编码为可打印的ASCII字符序列。目的是传输Unicode数据。主要的区别在于不用等号=补餘,因为该字符通常需要大量的转译。

    标准可见 RFC 2152,《A Mail-Safe Transformation Format of Unicode》。

    URL

    Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java持久化系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。

    然而,标准的Base64并不适合直接放在URL裡传输,因为URL编码器会把标准Base64中的/+字符变为形如%XX的形式,而这些%号在存入数据库时还需要再进行转换,因为ANSI SQL中已将%号用作通配符。

    为解决此问题,可采用一种用于URL的改进Base64编码,它不在末尾填充=号,并将标准Base64中的+/分别改成了-_,这样就免去了在URL编解码和数据库存储时所要做的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

    另有一种用于正则表达式的改进Base64变种,它将+/改成了!-,因为+*以及前面在IRCu中用到的[]正则表达式中都可能具有特殊含义。

    此外还有一些变种,它们将+/改为_-._(用作编程语言中的标识符名称)或.-(用于XML中的Nmtoken)甚至_:(用于XML中的Name)。

    其他

    • 垃圾訊息傳播者用Base64來避過反垃圾郵件工具,因為那些工具通常都不會翻譯Base64的訊息。
    • LDIF檔案,Base64用作编码字串。

    相关事件

    • 2018年2月电子邮件程序 Exim 发现重大漏洞,编号为 CVE-2018-6789 页面存档备份,存于緩衝區溢位漏洞允许攻击者在服务器上远程执行恶意代码。漏洞位于 base64 解码函数中,影响 Exim v4.90.1 之前的所有版本,多达 40 万服务器受到影响。[1][2]

    参见

    参考资料

    1. . [2018-03-07]. (原始内容存档于2018-07-23).
    2. . [2018-03-07]. (原始内容存档于2018-03-08).

    外部链接

    在线Base64编码


    This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.