Base64

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

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

RFC 4648 标准的 Base64 索引表
 十进制  二进制  字符   十进制  二进制  字符   十进制  二进制  字符   十进制  二进制  字符  0  000000  A  16  010000  Q  32  100000  g  48  110000  w  1  000001  B  17  010001  R  33  100001  h  49  110001  x  2  000010  C  18  010010  S  34  100010  i  50  110010  y  3  000011  D  19  010011  T  35  100011  j  51  110011  z  4  000100  E  20  010100  U  36  100100  k  52  110100  0  5  000101  F  21  010101  V  37  100101  l  53  110101  1  6  000110  G  22  010110  W  38  100110  m  54  110110  2  7  000111  H  23  010111  X  39  100111  n  55  110111  3  8  001000  I  24  011000  Y  40  101000  o  56  111000  4  9  001001  J  25  011001  Z  41  101001  p  57  111001  5 10  001010  K  26  011010  a  42  101010  q  58  111010  6 11  001011  L  27  011011  b  43  101011  r  59  111011  7 12  001100  M  28  011100  c  44  101100  s  60  111100  8 13  001101  N  29  011101  d  45  101101  t  61  111101  9 14  001110  O  30  011110  e  46  101110  u  62  111110  + 15  001111  P  31  011111  f  47  101111  v  63  111111  / 填充  =

 示例 
舉例來說，一段引用自托马斯·霍布斯《利维坦》的文句：
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編碼之後變成：

编码「Man」的結果為，詳細原理如下：
 文本 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&numsp;&numsp;&numsp;&numsp;&numsp;&numsp;&numsp;&numsp;&numsp;&numsp;&numsp;&numsp; 二进制位（補0）010000010000留空填充留空填充 Base64编码 Q Q== 文本（2 Byte） B C 二进制位010000100100001100&numsp;&numsp;&numsp;&numsp;&numsp;&numsp; 二进制位（補0）010000100100001100留空填充 Base64编码 Q k M=

 应用 

变种
base64编码对应的64个可打印字符在一些特定的程序或协议中可能不适合使用，特别是字符表第62位（+）、63位（/）和填充字符（=），因此存在一些如下的变种：
 编码 编码字符 换行的处理 是否解码非编码字符 第62位 第63位 填充 分隔符 行字符数 校验和 ：用于隐私增强电邮的Base64（已弃用） +  /          ：用于MIME的Base64 +  /          : 用于UTF-7的Base64 +  /   colspan=3    ：用于IMAP协议邮箱命名的Base64 +  ,   colspan=3    ：标准base64 +  /    colspan=3     ：base64url（URL和文件名安全标准） -  _   colspan=3     ：用于OpenPGP的Radix-64 +  /         

 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 
在等软件所使用的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的訊息。
 在檔案，Base64用作编码字串。

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

 参见 
  Base58


 Quoted-printable
 uuencode


 URL

 参考资料 

 外部链接 
RFC 1421（Privacy Enhancement for Electronic Internet Mail）
RFC 2045（MIME）
RFC 3548（The Base16, Base32, and Base64 Data Encodings）在 RFC 4648 中被替代
 Online Base64 Encoding 
 Online Base64 Decoding 
 在线Base64编码 
 在线Base64解码 

在线Base64编码

Category:标准
Category:文件格式
Category:数据序列化格式