前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Rust项目推荐】使用Rust生成Youtube风格的ID

【Rust项目推荐】使用Rust生成Youtube风格的ID

作者头像
MikeLoveRust
发布2019-12-30 16:24:58
7210
发布2019-12-30 16:24:58
举报

人们常用数据库的自增ID作为web资源的ID,形如/articles/1230098/videos/9527这样的。虽然这种做法很简单,但是也增加了被全量爬取数据的风险。爬虫制作者只要指定一个起始ID,然后不停的自增可以请求全部数据。

如果你上过油管并仔细观察过油管视频页面的地址,就会发现油管的视频ID是由字母数字和下划线等组成的。如果前端通过字母ID请求资源,后端拿到字母ID后通过某种规则将其解码为数字ID,然后再通过该数字ID去数据库读取数据。这种做法在一定程度上可以防止直接使用自增ID带来的问题。

笔者出于好奇,也在网上搜索了相关问题。一篇博文给出了一种可行的实现方式,看起来效果不错。这篇文章已经是5年前的了,博主使用php实现了初版,然后各路网友给出了由不同语言实现的版本。作为一个RUST爱好者,发现居然没有RUST版,当然不能忍,当即就想动手来做。代码也没多少,没花多少时间就写完了。不过由于是依样画葫芦,没能完全理解其中的原理,笔者也是很担忧这东西能不能在实际项目中使用,毕竟如果生成的ID有重复,又或是解码结果和原数字ID不一致的话就凉凉了。所以写完就那么放着了。

突然有一天,笔者感觉自己灵光一闪,突然就领悟了其中的数学原理。这尼玛不就是一个10进制和N进制的换算问题么。比如十六进制就是用16个数字和字母组成的字符集来表示数字,那么这篇博文说的就是用N个字符来表示数字啊!但是我看博主的实现代码完全没看出来,我真是太菜了!

可能有些朋友对这个N进制还是有点疑惑,我这里再稍微说下。假如我们要用三个字母xyz来表示数字。如果用一位字母,则可以表示0-2。如果是两位就是0-8,例如XX表示0,XY表示1(如果对这里不能理解,可以去看下2进制和16进制)。M位就是0到3的M次方减一。

好了我们来说下具体实现,假如我们要用abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-_来表示生成ID,用一位字母就可以表示0-63这些ID,二位可以表示64的2次方,3位就是64的3次方。随着位数的增加,可以表示的数字也越来越大。理论上,如果对生成字母长度不设上限,可以表示无穷大。我们的RUST里的u128最大值是340282366920938463463374607431768211455

那么如果要表示这个数字,我们的字符ID需要22位。64的22次方已经超过了这个范围。

在理解了这个原理之后,笔者把之前依样画葫芦写下的代码根据自己的思路重构了一番,解决了该博主实现中的一些bug吧,同时也处理了一些可能的overflow奔溃。项目叫做alphaid,放在GitHub了。笔者还写了详细的文档和较多的测试用例,发布到了crates.io。

这里放一个简单的例子:

代码语言:javascript
复制
use alphaid::AlphaId;

let alphaid = AlphaId::new();
assert_eq!(alphaid.encode(1350997667), b"90F7qb");
assert_eq!(alphaid.decode(b"90F7qb"), Ok(1350997667));

你也可以采用自己的字符集,最好将字母打乱顺序,这样的话写爬虫的人也猜不出规则了:

代码语言:javascript
复制
let alphaid = AlphaId::builder().pad(2)
    .chars("ABCDEFGHIJKLMNOPQRSTUVWXYZ".as_bytes().to_vec())
    .build();
assert_eq!(alphaid.encode(0), b"AB");
assert_eq!(alphaid.decode(b"AB"), Ok(0));

友情提示,最好把c, s, f, h, u, i, t这些字母拿掉,否则产生了fuck等这些不好的词汇就不好咯!!

注意,这种方式只是一种思路,不代表youtube就采用了这种方式。

最后,如果本文章或者本项目对你有帮助的话,欢迎点赞!有什么反馈也欢迎提出。

附上项目地址 github https://github.com/importcjj/alphaid

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust语言学习交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档