本帖最后由 RommHui 于 2022-6-19 03:07 编辑
一、引言Base64 在现在的网络中大量的使用,它是用于解决把不可见字节转为可见字符的算法。我们一直使用,却不知道其原理,我觉得不太行。我希望通过这篇文章,可以让读者知道,它是怎么样运作的,为什么可以让不可见的字节转成可见的字符。为什么转换后的数据长度是原来的 4 / 3。 二、基本原理首先Base64为什么叫Base64,我觉得是因为转换后除去等号(=)最多只会出现64个字符。这64个字符分别是 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 +/ 26 + 26 + 10 + 2 = 64
刚好就是64个,我觉得这就是叫Base64的原因。
以字符串“123”为例子,base64结果为“MTIz”。“123”长度为3个字节,正如上图第一行的框框表示的那样。然后在3个字节24个位,平均分割成4份,也就是以6位一份(8 x 3 = 6 x 4 = 24)。然后将4份6位的数据前面添加2个位且都为0。这样一来,就完成了3个字节变4个字节的操作了。因为是6个位,所以 2 的 6 次方就是 64。刚好可以和前面提及的64个字符对应得上。例子中的第一个字节 00001100 转成 10 进制也就是 12 ,也就是 “M” 的位置,所以第一个字节转换成了 “M”。第二个字节 00010011 转成 10 进制也就是 19,可以和 “T” 的位置对应得上。后面 2 个字节也是相同的道理,在这里就不多赘述了,读者可自己验证一下。 也正是因为 Base64 会把 3 个字节转成 4 个字节,所以数据才会是原来数据长度的 4 / 3。 到了这里,你可能还会有疑惑,就是,你可能见过结尾带 “=” (等于号)的 Base64 字符串情况。那下面我就继续用例子说明。 首先,我们知道 Base64 是 3 个字节转 4 个字节的,但是,不是所有的数据长度都是刚好是 3 的倍数,所以就需要用到“=”(等于号)来在后面进行填充。
以 “1” 为例子,经过 Base64 转换后得到 “MQ==”,为什么会这样呢?因为,”1″ 只是占 1 个字节,不够 3 个字节来转 4 个字节,所以就需要 “=”(等于号)来填充后面两个没有缺少的字节,来确保是 4 个字节。从这里可以看出 Base64 字符串长度都是偶数,并且是 4 的整数倍。 三、代码- function encodeUint8ArrayToBase64(u8a){
- var LIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var s = "";
- for(var i = 0;i<u8a.length;i += 3){
- s += LIST[(u8a[i] & 0b11111100) >> 2];
- if(typeof(u8a[i+1])=="undefined"){
- s += LIST[((u8a[i] & 0b00000011) << 4)];
- s += "==";
- }else{
- s += LIST[((u8a[i] & 0b00000011) << 4) + ((u8a[i+1] & 0b11110000) >> 4)];
- if(typeof(u8a[i+2])=="undefined"){
- s += LIST[((u8a[i+1] & 0b00001111) << 2)];
- s += "=";
- }else{
- s += LIST[((u8a[i+1] & 0b00001111) << 2) + ((u8a[i+2] & 0b11000000) >> 6)];
- s += LIST[(u8a[i+2] & 0b00111111)];
- }
- }
- }
- return s;
- }
复制代码
|