首先解释一下什么是短网址。你收到过的短信里应该有长成这样的网址:https://t.cn/a6v27
,这就是一种短网址,或者叫短链。点击该网址,会发现跳转到了一个拥有很长地址的网站。这种通过短网址跳转到原网站的技术主要有两个好处:
一是对短信发送方,可以减小短信内容,降低流量消耗,我们知道网络运营商是按流量使用大小计费的。二是对用户来说,短网址较原本的长网址更美观,同时也使得短信内容更加紧凑,便于用户阅读。
短网址的核心原理很简单,一句话概括就是:短网址服务器将对某个短网址的访问请求重定向到其对应的原网址。所以需要服务端维护短网址到原网址的映射,也需要向原网址所有者提供注册映射的接口(一般为网页)。
当然,需要注意的是,选用的短网址生成算法要保证极小的碰撞率,同时要避免被批量刷出。不过这不在这篇文章讨论的范围。
进入正题,所谓零宽度短网址就是指没有唯一代表该网址的部分,如上面例子中的 a6v27
部分。以 zws.im 为例,该平台生成的短网址全都长这样:
|
|
没错,就是它本身的样子。那他怎么识别不同原网址?原理其实很简单,该平台也对其原理做了说明。我们知道 unicode 字符集包含了地球上几乎所有的符号文字。而在很多国家的语言中,都有连字1 的现象,比如波斯语中的「我想要」可写为下面两种形式2
第一种就是连字形式。为避免字体文件将字符渲染成连字形式,unicode 字符集中出现了不占宽度的字符,如上图中的第二种写法中的红线部分。该字符的 unicode 码为 200b
,在 utf8 编码中占 3 个字节,其 HTML 代码为 &zwnj
。使用了该零宽度字符后,字体文件就不会将可以连字的字母进行连字处理。
但是,这种零宽度字符是肯定会占空间的,你可以打开浏览器的控制台运行下面代码试试看
|
|
我们知道 JavaScript 对象的 length 属性返回的是字符串中字符编码单元的数量3,故这行代码会返回 1,表示有一个字符。所以使用这种字符来生成短网址的方法,并不能体现上述节省流量的好处。更直观一点,我们拿一条该平台生成的短链接来试试
|
|
可以看到,现在返回了 28,而不是本身 15 的长度,说明在地址后面还有 13 个零宽度的字符。不过我觉得这种零宽度短链接是种很酷的东西,所以我又收集了几组零宽度字符,它们的 unicode 码分别是
- 200b ~ 200f
- 2028 ~ 202e
- 2060 ~ 206f
- feff, 180e
打算用这些字符的不同数量的排列组合对应到正整数上,由此自己实现一个零宽度短网址生成器(挖坑+1)。