Base64
定义
Base64是一种把任意字节序列改写为由64种可打印字符组成的文本的编码方法,其输出只含ASCII范围内的可印刷符号,因此可以放进原本只接受文本的通道[1][3]。按RFC 4648第4节规定的标准字母表,这64个字符依次是26个大写拉丁字母、26个小写拉丁字母、10个阿拉伯数字,再加加号与斜线,另以等号作为末尾的填充符号[1][3]。
此外还有一种URL与文件名安全的形式,规定于同一份文档的第5节,它把加号和斜线换成连字符与下划线,并且可以省略填充的等号[1][5]。严格说来,它只是一种可逆的表示转换,不改变信息内容,也不提供任何保密性,因而与加密不是同一类技术[6][7]。
原理
编码的核心动作是把位串重新切分。每3个8位字节合成24位,再把这24位按每6位一组切成4组,每组取值落在0至63之间,用它去查字母表得到一个字符;由于6与8的最小公倍数是24,3字节恰好对应4个字符而不浪费分组[3]。这一步可用下式表示:每3字节的24位 $\to$ 4组各6位 $\to$ 4个字符[1]。
以文本为例,字符序列Man经编码后得到TWFu:三个字母的ASCII码值连成24位,分成4组后分别对应索引19、22、5、46,再查表得到T、W、F、u[3]。
末尾不足3字节时需要补位。若剩下1个字节,以0补足至24位,输出2个字符并追加2个等号;若剩下2个字节,则输出3个字符并追加1个等号,例如字母a编码为YQ==[6]。解码则反向进行,把4个字符还原成4个6位数值,拼接后取出原来的字节;RFC 4648要求编码端把补入的尾随位设为零,解码端是否因尾随位非零而报错可以自行选择[1]。
flowchart LR
A[原始字节 3 x 8 位] --> B[合并为 24 位]
B --> C[切分为 4 组 6 位]
C --> D[每组取值 0-63]
D --> E[查字母表得 4 个字符]
E --> F[不足 4 字符时以 = 补齐]
发展历程
Base64的早期形态出现在为电子邮件提供隐私增强的规范RFC 1421中,该文档给出了一套64字符的字母表与相应的编码机制,并用等号补齐输出[8][9]。1992年6月发布的RFC 1341在规范中使用了Base64这一名称,此后多用途互联网邮件扩展(MIME)的RFC 2045沿用了同一套字母表和编码方式[8]。
MIME对编码行作了限制:不固定行长,但最长不超过76个字符,行与行之间以回车换行分隔,解码时应忽略字母表之外的字符[8]。由于这些附加要求,符合MIME的编码数据长度通常约为原文的137%,很短的报文中因头部开销比例还会更高[8]。
此后出现了若干变体。UTF-7使用不带填充的改进型Base64,以便在可传7位的SMTP通道中传送UTF-16文本;OpenPGP则定义了Radix-64,在MIME式编码之外附加一个可选的24位校验值[10]。为统一各种写法,RFC 3548曾试图把RFC 1421与RFC 2045的规范合并,2006年10月发布的RFC 4648取代了它,集中规定Base64、Base32与Base16,并同时给出标准字母表与URL安全字母表[8][11]。
应用
最早也最典型的用途是电子邮件。在MIME格式的邮件中指定Base64作为传输编码,就可以把图片、附件等字节序列变成纯ASCII文本随信发送,避免网关或协议改写控制字符、转换换行而造成内容损坏[4][12]。同样的思路也用于在XML或SOAP消息中嵌入二进制数据,以及以数据URI的形式把图片等资源直接写进网页样式或文档[1][13]。
需要在URL、文件名中携带二进制信息时,通常改用URL安全变体,把加号和斜线替换掉,使结果不必再经百分号转义即可放进路径或查询参数[1][2]。
开发实践中,多数语言在标准库里内置了相应函数,例如Python的base64模块同时提供标准与URL安全两套接口,旧接口还按RFC 2045的规定每76个字符插入换行[5]。浏览器环境长期以btoa和atob两个函数完成编码与解码,较新的JavaScript实现则在Uint8Array上提供fromBase64与toBase64等方法[1]。
OpenPGP的ASCII Armor、LDIF目录文件、以及一些把二进制资源嵌入脚本的打包做法也使用Base64或其近似变体[9][8]。
局限
体积膨胀是最直接的代价。每个Base64字符只承载6位信息,3字节变4字符,编码结果通常比原文大约三分之一,符合MIME规范时因换行与头部开销还会更多;极短的数据膨胀比例尤其明显,单个字符a编码为YQ==,长度增加到原来的4倍[1][8]。这种膨胀属于表示层的增加,编码本身不做压缩,已压缩过的图片或音视频转成Base64后不会变小,只会变长[14]。
膨胀还会带来额外计算。解码需要消耗处理资源,数据量大时开销较为可观,因此对体积敏感或数据量巨大的传输,直接使用二进制通道往往更合适[7][15]。
Base64不能提供保密性。编码规则公开且完全可逆,任何人都能把结果还原成原始内容,所以不宜用它来处理口令或敏感数据,也不应把它当作散列或加密手段[6]。它同样不校验内容是否被改动;需要完整性保护时,要在其上叠加签名或校验机制,例如Radix-64附加的24位校验值[10]。
标准字母表也有使用上的不便。加号与斜线在URL中有保留含义,等号在查询字符串和某些语境下需要转义,这也是URL安全变体存在的原因;此外,字符集之外的字符如何处理、是否强制填充,不同规范与实现的处理并不一致,跨系统交换时需要事先确认对方采用的变体[3][9]。
参见
参考资料
- Base64 [引用日期2026-10-29]
- 图文详情——科普中国资源服务 [引用日期2026-10-29]
- 一篇文章彻底弄懂Base64编码原理 [引用日期2026-10-29]
- Base64 [引用日期2026-10-29]
- base64 --- Base16, Base32, Base64, Base85 数据编码 [引用日期2026-10-29]
- 深入浅出理解base编码 [引用日期2026-10-29]
- 消息体编码选择指南 - Alibaba Cloud [引用日期2026-10-29]
- wikipedia.org 上的网页 [引用日期2026-10-29]
- Notes on Base64 as it exists [引用日期2026-10-29]
- wikipedia.org 上的网页 [引用日期2026-10-29]
- ITU-T work programme - Committed to connecting the world [引用日期2026-10-29]
- Base64 编码 & 解码器,原理详解 | 私密、在浏览器中运行 [引用日期2026-10-29]
- 本发明使用 BASE64 编码将二进制数据转换成以显示的字符文本格式后嵌入 SOAP/XML 消息 [引用日期2026-10-29]
- 图片转 Base64 后为什么变大:Data URI、上传和外链怎么选 [引用日期2026-10-29]
- Web 服務、不透明資料和附件問題 - 基底 64 編碼已過一段時間,而且可能收到不透明資料問題的不雅內容 [引用日期2026-10-29]