一、概念
base64编码不提供加密,只是将一种形式的数据转化为另一种形式。
Base64编码使用二进制表示,字符串的每一个字符由8个字节表示。
二、Base64字母表
支持字符(可以进行编码的字符):字母从A-Z,a-z,数字0-9,以及加号+、斜杠/和等号组成,一共65个字符,因而我们可以用6位二进制表示某个字符。
注:base64字母表中的第65个字符=
等号不参与转码,只是作为占位符出现(base64编码转化为字符串时空字符使用=
作为占位符),因而参与转化的字符一共是2^6=64
个,所以可以用八位二进制数值表示。
码值 | 字符 | 码值 | 字符 | 码值 | 字符 | 码值 | 字符 |
---|---|---|---|---|---|---|---|
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 | / |
64 | = |
三、编码原理
以字符串hat
为例。
将每一个字符都转化为二进制
01101000-01100001-01110100
将二进制编码长度转换为6
011010-000110-000101-110100
将每个6位转化为数字
26-6-5-52
使用base64字母表替换数字
a-G-F-0
转化结果就是
aGF0
。字符串的每三个字节最终表示为四个字节,所以生成的base64编码字符串总是比原始字符串大33%。
到这里,编码原理就结束了。
四、代码实现
在对一个字符串进行base64编码之前需要注意一点,因为每一个字符是由8位二进制码表示,因而base64编码无法将ASCII编码中排名超过255的字符进行编码。
由此在编码转换之前应先做一个合法字符校验。
const isBase64EncodeSymbolIllegal = str => {
return [...str].some(v => {
return v.charCodeAt() > 255
})
}
当然,以上这个函数现在已经用不上了,因为我们现在可以用更方便的方法进行base64字符与一般字符相互转化。使用atob()
,btoa()
进行编码转化。
base64编码 btoa()
将普通字符串进行base64编码。
btoa('test') // "dGVzdA=="
btoa('测试') //Throw Error: The string to be encoded contains characters outside of the Latin1 range.
base64解码 atob()
将base64码转化为一般字符串。
atob('YWRtaW4=') //"admin"
atob('admin') //Throw Error: The string to be decoded is not correctly encoded.
2018-8-2新增
btoa()
与atob()
代码实现,使用Buffer转换。
const atob = str => new Buffer(str, 'base64').toString('binary');
const btoa = str => new Buffer(str, 'binary').toString('base64');