atob和btoa函数

642 阅读4分钟

我正在参加「掘金·启航计划」

window对象下有atobbtoa两个函数,用于 base64 和 ASCII 码之间的转换

函数名功能参数
atobbase64 字符串转 ASCII 码字符串base64 字符串
btoaASCII 码字符串转 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安全编码

image.png

image.png

首先查询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

完毕!