我正在参加「掘金·启航计划」
window对象下有atob和btoa两个函数,用于 base64 和 ASCII 码之间的转换
| 函数名 | 功能 | 参数 |
|---|---|---|
| atob | base64 字符串转 ASCII 码字符串 | base64 字符串 |
| btoa | ASCII 码字符串转 base64 字符串 | ASCII 码字符串 |
实际效果:
window.btoa('A')
'QQ=='
window.atob('QQ==')
'A'
但是这名字却是反的,很奇怪了,只能记作atob是a开头就是要获得ascii码,btoa是b开头就是要获得base64码
我们来看btoa('A')是怎么经历了什么,即ascii码转base64码过程
先了解ascii码和base64码的关系
-
1、一个字节是8位,ascii码是用后面7位,可表示128个字符,但是其中只有95个是可见字符
-
2、在网络中不可见字符容易丢失,于是为了安全性需要全部转为可见字符
-
3、base64是只有一个字节的后面6位,可表示64个字符,于是方法就是把ascii码映射到base64编码
-
4、于是方法是将字符串三个字符一组对应二进制24位,这24位再6个一组分为4个字节,后面不足补0,如果6位都是0则显示=号
-
5、最终文件体积增加了33%,都转换为base64安全编码
首先查询A的ascii码对照表,得出A对应65
`A`.charCodeAt(0)
65
65转为二进制
A -> 65 -> 01000001
ascii码二进制补全24位
因为字符串只有A,不满足三个字符,所以后面差的都是0
A -> 65 -> 01000001 -> 01000001 00000000 00000000
24位拆分6个一组得4组
A -> 65 -> 01000001 -> 01000001 00000000 00000000 -> 010000 010000 000000 000000
将这四组每个对应base64码
因为010000的十进制就是16,查base64码得到Q,前面两组都是Q,最后两组全是0,就用=号补位表示
A -> 65 -> 01000001 -> 01000001 00000000 00000000 -> 010000 010000 000000 000000 -> QQ==
修补规则
在url中=+/这三个字符会有问题,所以这三个字符额外单独处理
-
不在末尾填充
=号 -
+用*替换 -
/用-替换
举例
验证 www.murzwin.com/base64vlq.h…
ABC -> 65,66,67 -> 01000001 01000010 01000011 -> 010000 010100 001001 000011 -> 16,20,9,3 -> QUJD
Base64 VLQ
VLQ 是 Variable-length quantity 的缩写,用以通过任意位二进制精简地表示很大的数值。
AAgBC
// 先将每一位按 base64 编码还原为 6 位二进制字符串
=> 000000 000000 100000 000001 000010
// 然后进行分组,最高位的含义是是否连续,如果是 1 则连续,所以要和后面的放到一组
=> (000000) (000000) (100000 000001) (000010)
// 分完组之后,最高位就可以移除了,由于 VLQ 只能表示 -15 ~ 15 之间的数,所以有的数值是切割之后来表示的,所以我们要先还原它,去除最高位倒序拼接即可
=> (00000) (00000) (0000100000) (00010)
// 之后将最低位的符号位去除,虽然 VLQ 可以表示正负,但代码中没有负行负列这么一说,通常都是 0,所以直接去掉就行了
=> (0000) (0000) (000010000) (0001)
// 最后还原为十进制数
=> 0 0 16 1
完毕!