简介
Base64是一种编码方式,与ASCII码类似,Base64编码使用6个二进制位表示一个字符,范围用二进制表示为000000~111111,2^6=64,所以可以表示64个字符,如下图所示:
ASCII使用7个二进制位来表示一个字符,最高位为0,范围用二进制表示为00000000~01111111,用十进制表示为0~127,每个编码代表一个字符,所以可以表示128个不同的字符,包括字母、数字、符号
编码原理和过程
先看一个例子,将HelloWorld
用Base64编码
得出结果:SGVsbG9Xb3JsZA==
。接下来介绍是如何得出这个结果的,编码分为三个步骤
- 将编码对象转换成二进制
- 以6位为单位分组
- 转换成十进制并对照Base64编码表得出结果
将编码对象转换成二进制
这里的编码对象是HelloWorld
,找到每个字符对应的ASCII编码,再转换成二进制
字符 | ASCII编码 | 二进制 |
H | 72 | 01001000 |
e | 101 | 01100101 |
l | 108 | 01101100 |
l | 108 | 01101100 |
o | 111 | 01101111 |
W | 87 | 01010111 |
o | 111 | 01101111 |
r | 114 | 01110010 |
l | 108 | 01101100 |
d | 100 | 01100100 |
按照顺序得出来结果为:
01001000
01100101
01101100
01101100
01101111
01010111
01101111
01110010
01101100
01100100
以6位为单位分组
将上面得到的二进制分组,一组6个二进制位,第一组为010010,第二组为000110......依此类推
010010
000110
010101
101100
011011
000110
111101
010111
011011
110111
001001
101100
011001
00
如果最后一组的二进制位不足6位,用0补齐,所以最终结果为
010010
000110
010101
101100
011011
000110
111101
010111
011011
110111
001001
101100
011001
000000
转换成十进制并对照Base64编码表得出结果
二进制 | 十进制 | Base64编码 |
010010 | 18 | S |
000110 | 6 | G |
010101 | 21 | V |
101100 | 44 | s |
011011 | 27 | b |
000110 | 6 | G |
111101 | 61 | 9 |
010111 | 23 | X |
011011 | 27 | b |
110111 | 55 | 3 |
001001 | 9 | J |
101100 | 44 | s |
011001 | 25 | Z |
000000 | 0 | A |
到这里得出的结果为SGVsbG9Xb3JsZA
注意:编码之后的长度需要是4的倍数,如果不满足要在结尾用=补齐
比如SGVs bG9X b3Js ZA的长度是14,要补上两个=,所以编码的结果为SGVsbG9Xb3JsZA==
补充:
- 其他如Base16、Base32编码的原理都是一样的,不过是位数和编码表不一样
- Base64只是一种编码方式,不是加密算法,所有的数据都是明文存储的
应用
编码资源文件
比如:在html文档中渲染一张Base64图片
注意:通过Base64编码后的数据通常比原始数据大1/3,所以这种方式仅适用于小图片,如果图片较大,在Base64编码后字符串会非常大,影响页面加载进度,这种情况不适合用Base64编码
在HTTP中传递较长的标识消息
比如使用Base64将一个较长的标识符(128bit的UUID)编码为字符串,用作表单和GET请求中的参数。
注意:标准的Base64编码不适合直接放到URL中传输,因为URL编码器会把Base64中的/
和+
变成%xxx
的形式,我们可以采取一些措施来避免这个问题,比如将Base64中的/
和+
改成_
和-
等字符,避免URL编码器转换