你真的懂 Base64 吗?短链服务常用的 Base62 呢?


黄山的冬天,中国 (© Hung Chung Chih/Shutterstock)

Base64

前端的日常开发中可能会接触到 Base64 ,比如页面上的小图片,在为了节省网络资源的情况下,通常会将图片转为 Base64 直接嵌入到 html 或者 css 里。这里,我们先来看看 Base64 是什么,以及 Base64 编码做了什么。

什么是 Base64

Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。一般来说,64个字符包括 A-Z,a-z,0-9 以及 +/ 两个字符(via)。换句话说, Base64 可以将二进制数据转换为这 64 个字符来表示,数据来源可以是图片,也可以是任意的字符串。

Base64 做了些什么

上面提到了 Base64 做的其实就是将二进制数据按照对应规则进行转化,转化的流程其实也很简单

  1. 得到一份二进制数据
  2. 将二进制数据 6位 一组进行划分,并进行适当的补位
  3. 按照 Base64 索引表,将每组数据转换为 Base64 索引表对应的字符,补位位置用 =

下面我们来尝试一下将 aa 这个字符串进行一下 Base64 编码:

第一步:通过 ASCII 表将 aa 转换为对应的二进制表示

可知 a 在 ASCII 表对应的二进制表示为 0110 0001,则 aa 对应为 0110 0001 0110 0001
注:

  1. ascii 参考
  2. 中文等其他字符参考其他表(UTF-8)进行转换即可
第二步:数据分组和补位

按 6 位一组划分后 011000 010110 0001,我们发现数据还少两位,所以我们需要按规则对数据进行补位,补一字节(8位),二进制数据变为 0110 0001 0110 0001 0000 0000,划分为 011000 010110 000100 000000

第三步:查 Base64 索引表 进行转换

参考一张常用的索引表 可知 aa = 011000 010110 000100 000000 对应为 011000(Y ) 010110(W ) 000100(E ) 000000(补位= ) 即 YWE=,我们就得到了 aa 的 Base64 编码为 YWE= ,是不是挺简单。

Base62

说完了 Base64,我们再来聊聊 Base62。在通过 url 传递数据的场景下,通过 Base64 进行编码的数据会带来问题(Base64 中的 / 等可能会带来路径的解析异常),所以在 Base62 里,去掉了 +/= 字符。 说到这里,大家可能觉得就讲完了,Base62 就是丢掉了几个不安全的字符而已,其余转换方法和 Base64 一样,我起初也是这么认为的。

不一样的 Base62 结果

当我尝试对 aa 进行 Base62 编码时,按推算好像也不太对? = 补位已经被去掉了,怎么来做实现呢? 在我找了几个 online 转换进行测试后,发现 aa 对应的 Base62 编码为 6U5 看着跟 Base64 毫无关系对吧,实际上也是的。

揭开面纱看看

查了几份资料以及现有的仓库实现后,我发现 Base62 编码的流程是这样的:

  1. 获得一份二进制数据
  2. 二进制数据 转 10进制
  3. 10进制 转 62进制(按索引表)

我们再来试试将 aa 转 Base62:

第一步:转二进制

aa 对应 0110 0001 0110 0001

第二步:转10进制

0110000101100001 对应十进制为 24929

第三步:转62进制(参考索引表)

24929 = 6622+30 62+5

按表可知,6=6 30=U 5=5,即 6U5

注:

  1. 索引表可以自行更换,并不一定是上图顺序
  2. 现有的仓库实现里,部分只实现了 10进制 转 62进制( base62/base62.js),有的实现了更完整的转换 ( tuupola/base62

分析一下原因

说实话我查到的资料不多,但是根据 en.wikipedia.org/wiki/Talk:B... 猜测,文里提到 Base64 后的数据会膨胀到 133% 。Base62 还存在对数据进行压缩的改进,所以采用了这样与 Base64 差别有点大的方式来设计。

总结一下

文章简单的谈了谈 Base64 是什么,怎么实现以及 Base62 的实现,并分析了一下 Base62 设计的初衷,整体来说还是挺简单,希望对你有所帮助 :)

相关推荐
小白学习日记38 分钟前
【复习】HTML常用标签<table>
前端·html
丁总学Java1 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
yanlele1 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
懒羊羊大王呀2 小时前
CSS——属性值计算
前端·css
睡觉然后上课2 小时前
c基础面试题
c语言·开发语言·c++·面试
xgq2 小时前
使用File System Access API 直接读写本地文件
前端·javascript·面试
用户3157476081352 小时前
前端之路-了解原型和原型链
前端
永远不打烊2 小时前
librtmp 原生API做直播推流
前端
北极小狐2 小时前
浏览器事件处理机制:从硬件中断到事件驱动
前端
无咎.lsy2 小时前
vue之vuex的使用及举例
前端·javascript·vue.js