Base64编码


Base64
是一种基于64个可打印字符来表示二进制数据的表示方法。因为{\displaystyle 2^{6}=64}{\displaystyle 2^{6}=64},因此每6个比特为一个单元,对应某个可打印字符。3个字节有24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。它可用来做为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Za-z数字0-9,这样共有62个字符,此外两个可打印符号在不一样的系统中而不一样。一些如uuencode的其余编码方法,和以后BinHex的版本使用不一样的64字符集来表明6个二进制数字,可是不被称为Base64。


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

MIME

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

完整的Base64定义可见RFC 1421和RFC 2045。编码后的数据比原始数据略长,为原来的{\displaystyle {\frac {4}{3}}}{\frac {4}{3}}。在电子邮件中,根据RFC 822规定,每76个字符,还须要加上一个回车换行。能够估算编码后数据长度大约为原长的135.1%。正则表达式

转换的时候,将3字节的数据,前后放入一个24位的缓冲区中,先来的字节占高位。数据不足3字节的话,于缓冲器中剩下的比特用0补足。每次取出6比特(由于{\displaystyle 2^{6}=64}{\displaystyle 2^{6}=64}),按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符做为编码后的输出,直到所有输入数据转换完成。算法

若原数据长度不是3的倍数时且剩下1个输入数据,则在编码结果后加2个=;若剩下2个输入数据,则在编码结果后加1个=数据库

例子

举例来讲,一段引用自托马斯·霍布斯利维坦》的文句:编程

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编码以后变成:服务器

TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
  • 编码“Man”
文本 M a n
ASCII编码 77 97 110
二进制位 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0
索引 19 22 5 46
Base64编码 T W F u

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

Base64索引表:函数

数值 字符   数值 字符   数值 字符   数值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

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

文本(1 Byte) A    
二进制位 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
二进制位(补0) 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Base64编码 Q Q = =
文本(2 Byte) B C  
二进制位 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
二进制位(补0) 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
Base64编码 Q k M =

UTF-7

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

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

IRCu

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

在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 万服务器受到影响。
相关文章
相关标签/搜索