简介
Base64 是一种用于传输 8Bit 字节码的编码方式,其可以将任意的二进制数据转换为可打印的 ASCII 字符串,用于在网络传输中方便的传输或存储数据。
一个常见的误区是将 Base64 看作为加密算法,实际上 Base64 只是一种编码方式,不具备加密功能。
相较于 ASCII 编码的使用 7Bit
(7
个二进制位)字节码来表示一个字符,Base64 使用 6Bit
字节码表示一个字符,即 2^6=64
个不同的字符。
这些字符包括 26
个大写英文字符、26
个小写英文字符、10
个数字字符和 2
个特殊字符 +
和 /
(=
用于填充)。
Base64 编码表如下:
Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding |
---|---|---|---|---|---|---|---|
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 | / |
编码步骤
若目标不是二进制数据,而是字符串,那么 Base64 首先将目标转换为二进制数据,这个步骤分为如下几步:
- 将字符串的每一个字符转换为其对应的
ASCII
码 - 对每一个
ASCII
码进行2
进制转换,不足8
位的前面补0
,得到8
位的二进制数 - 将所有二进制数拼接在一起,得到一个长串的完整二进制数
这里以字符串 Mari
为例
1 | Array.from( "Mari" ) |
在得到二进制数据后,Base64 将其按照 6
位一组进行分割,分割后不足 6
位在后面补零。
根据上面得到的结果,分割后得到:
1 | 010011 010110 000101 110010 011010 010000 |
然后将每一位根据 Base64 编码表进行转换,得到:
1 | TWFyaQ |
Base64 编码后的字符串长度需要为 4
的倍数,如果不足则需要使用 =
补充,因此对上方的结果作最后补充处理,得到:
1 | TWFyaQ== |
这就是 Base64 的编码步骤,依次方式反向操作也可以将 Base64 编码的字符串解码为原始数据。
JavaScript 中的操作方法
JavaScript 为我们提供了 btoa
和 atob
方法,用于进行 Base64 编码和解码。
1 | btoa( "Mari" ) // "TWFyaQ==" |
不过需要注意的是,btoa
方法不能处理由非 ASCII 码字符组成的字符串。在 ASCII 编码中,所有的字符均为单字节的。
但对于非 ASCII 字符例如汉字,其通常需要使用多个字节来表示,此时 btoa
方法会抛出异常。
1 | "M".codePointAt( 0 ).toString( 2 ) // "1001101" 单字节字符 |
因此若需要处理非 ASCII 字符,需要在中间进行一次转换操作,例如使用 encodeURIComponent
和 decodeURIComponent
方法。
1 | function base64Encode( str ) { |