目录

    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。基本使用格式如下:

    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 项目提供的库函数。

    <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 实现

    > 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 编码,其实就是把字符 + 和 / 分别变成 - 和 _ :

    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. 参考