Please enable Javascript to view the contents

Base64 编码

 ·  ☕ 3 分钟

1. 应用场景

1.1 Mail

由于 RFC821 要求邮件内容必须为 ASCII 码。当邮件中有其他的非ASCII字符或二进制数据时,就需要 Content-Transfer-Encoding,Base64是其中的一种方法。

1.2 URL

有些应用需要把二进制数据放到URL里,而URL只允许特定的一些ASCII字符。这时,也需要用到Base64编码。当然,这也只是对数据本身的编码,编码后的数据里面可能包含+/,真正放到URL里面时候,还需要 URL-Encoding,变成%XX模式。

1.3 HTML中内嵌图片

这种方式是将图片编码为 Base64 字符串放到 HTML 页面。当HTML页面加载完成之后,图片数据也就加载完了,而不需要单独发HTTP 请求。

data: URI定义于IETF标准的RFC 2397。基本使用格式如下:

1
data:[<MIME-type>][;base64|charset=some_charset],<data>

MIME-type 是嵌入数据的 MIME 类型,比如 PNG图片就是 image/png。如果紧接着是base64,那么说明后面的 data 采用Base64编码。

1.4 数字证书签名

CER、CRT、PEM、KEY证书,这一类证书为Base64编码的格式。

1.5 去可视化化处理

不推荐 Base64 用于加密,但是有些场景仅仅需要将一个简单的字符串,转换成不可识别的字符串。比如,Cookie、Signature 参数等。还有些博客使用 Base64 编码邮箱地址,避免收到垃圾邮件。

2. Base64 原理

2.1 Base64 编码

Base64编码要求把3个8位字节(38=24)转化为4个6位的字节(46=24),之后在6位的前面补两个0,形成8位一个字节的形式。当原数据不是3的整数倍时,如果最后剩下两个输入数据,在编码结果后加1个“=;如果最后剩下一个输入数据,编码结果后加2个“=;如果没有剩下任何数据,就什么都不要加。

2.2 Base64解码

解码是编码的逆过程,去掉尾部 =,按 8 位展开,如果不是 8 的整数倍,末尾补 0,转换为ASCII编码即可。

3. 前端 JavaScript 实现

这里主要使用的是 js-base64 项目提供的库函数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<script src="base64.js/2.1.9/base64.min.js"></script>
<script>
Base64.encode('有意思');  // 5pyJ5oSP5oCd
Base64.decode('5pyJ5oSP5oCd');  // 有意思

Base64.encode('/user/?name=test'); // L3VzZXIvP25hbWU9dGVzdA==
Base64.decode('L3VzZXIvP25hbWU9dGVzdA=='); // /user/?name=test

Base64.encodeURI('/user/?name=test'); // L3VzZXIvP25hbWU9dGVzdA
Base64.decode('L3VzZXIvP25hbWU9dGVzdA');  // /user/?name=test
</script>

4. 后端 Python 实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
> ipython
In [1]: import base64

In [2]: base64.b64encode('ascii_string')
Out [2]:'YXNjaWlfc3RyaW5n'

In [3]: base64.b64decode('YXNjaWlfc3RyaW5n')
Out [3]:'ascii_string'

In [4]: base64.b64encode(u'有意思'.encode('utf-8'))
Out [4]:'5pyJ5oSP5oCd'

In [5]: print base64.b64decode('5pyJ5oSP5oCd').decode('utf-8')
Out [5]:'有意思'

处理中文时,需要注意的是:由于Python base64 库按照 RFC 3548 实现,仅能处理 Byte 和 ASCII 字符。解决办法是:先把 Unicode 字符转换成 Byte 就可以了。

处理流程: Unicode -> Byte string -> Base64 String -> Byte String -> Unicode

由于标准的 Base64 编码后可能出现字符 + 和 / ,在 URL 中就不能直接作为参数,所以又有一种 “url safe” 的 Base64 编码,其实就是把字符 + 和 / 分别变成 - 和 _ :

1
2
3
4
5
6
7
8
In[1]: base64.b64encode('i\xb7\x1d\xfb\xef\xff')
Out[1]: 'abcd++//'

In[2]: base64.urlsafe_b64encode('i\xb7\x1d\xfb\xef\xff')
Out[2]: 'abcd--__'

In[3]: base64.urlsafe_b64decode('abcd--__')
Out[3]: 'i\xb7\x1d\xfb\xef\xff'

5. 参考


微信公众号
作者
微信公众号