你真的懂 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 设计的初衷,整体来说还是挺简单,希望对你有所帮助 :)

相关推荐
知识分享小能手3 小时前
Vue3 学习教程,从入门到精通,Axios 在 Vue 3 中的使用指南(37)
前端·javascript·vue.js·学习·typescript·vue·vue3
程序员码歌5 小时前
【零代码AI编程实战】AI灯塔导航-总结篇
android·前端·后端
用户21411832636026 小时前
免费玩转 AI 编程!Claude Code Router + Qwen3-Code 实战教程
前端
小小愿望7 小时前
前端无法获取响应头(如 Content-Disposition)的原因与解决方案
前端·后端
小小愿望7 小时前
项目启功需要添加SKIP_PREFLIGHT_CHECK=true该怎么办?
前端
烛阴7 小时前
精简之道:TypeScript 参数属性 (Parameter Properties) 详解
前端·javascript·typescript
海上彼尚8 小时前
使用 npm-run-all2 简化你的 npm 脚本工作流
前端·npm·node.js
开发者小天9 小时前
为什么 /deep/ 现在不推荐使用?
前端·javascript·node.js
恋喵大鲤鱼9 小时前
Golang 后台技术面试套题 1
面试·golang
why技术9 小时前
也是震惊到我了!家里有密码锁的注意了,这真不是 BUG,是 feature。
后端·面试