有趣的Python开源库之Hashids

Hashids是一个非常小巧的跨语言的开源库,它用来把数字编码成一个随机字符串。它不同于md5这种算法这种单向映射,Hashids除了编码还会解码。

拿论坛来说,一般帖子在数据库里的id都是顺序递增的,但是你可能不想在url上直接把id暴露出来,以免爬虫直接遍历id爬取你的内容,给你带来损失。那现在你就可以使用Hashids把这个id搞乱,让它失去顺序性,无法直接遍历,这样就可以直接提高了爬虫的门槛。著名的Youtube网站就是这么做的。

我们来看看它怎么使用 首先安装一下 pip install hashids

我们看到hashids不仅可以编码一个整数,还可以一次编码多个整数。解码的时候不需要对字符串进行分割,可以直接解码成多个整数。这在存储一个帖子的相关帖子时给我们多了一种选择,一般我们使用json打包多个帖子id放在帖子表的一个字段里,现在我们就可以使用hashids把它们编码成一个字符串塞进去了,可以节省一定的存储空间。不过,除此之外我想不到编码多个整数有什么其它的用途了。

hashids需要提供一个salt值,相当于编解码的私钥,别人不知道你的私钥,就无法编码出对应的帖子的展现key,也无法通过url上的展现key解码出对应的帖子id。所以想直接遍历你的帖子服务那就做不到了。

现在我们试试随便提供字符串,对它进行解码会怎样

我们看到这些字符串都是非法,所以hashids无法解码出对应的整数。

下面我们对一段连续整数进行编码

可以发现编码之后的值在直觉上是没有任何规律可言的。

鉴于hashids是如此的小巧,笔者随后对它的源代码进行了一番研究。首先看看它的构造器

我们发现可以设置编码后字符串的最小长度。如果你不设置这个最小长度,对于一个从0开始的自增id,编码出来的字符串长度一开始只有2位,但是随着id的增长,编码后的长度也越来越大,但是最终这个长度值越来越稳定,因为位数越大可以表达的数值就越多。如果我们设置了这个最小长度,在id没有恐怖的快速增长的情况下,那么编码出的长度一开始就是非常稳定的。

然后我们还可以设置映射字典。默认是base64[26+26+10]编码,如果你不喜欢大小写敏感,可以改成base36[26+10]编码,甚至可以改成火星文,如果你真这么无聊的话。

注意火星文的字典必须是unicode类型。不然你编码得到的不是火星文,而是乱码。具体实现算法我就跳过了,有点复杂,我就不讲了。

然后它还支持对16进制字符串进行编解码,看来mongodb的id也可以纳入进来了。

最后算法的实现原理,仔细研究了一下,有点复杂,很难三言两语讲清楚,有兴趣的话读者还是自己阅读官方文章吧。算法的作者不保证安全性,不建议将hashids用在安全领域。

维基百科提到一个理想的hash算法需要满足下面3个特性

  1. 正向计算hash很容易
  2. 反向破解hash极其困难
  3. hash值碰撞概率极小

hashids满足第1和第3条,正向计算hash很快,hash值完全没有碰撞,保证了唯一性。如果知道salt值,还可以逆向通过hash值计算出原值。那第2条是否满足取决于你的salt秘钥有多容易被攻击者拿到。如果你的salt秘钥来自于常用字典单词,那攻击者可以通过彩虹字典快速将秘钥破解。你把秘钥好好保护,设置的随机一点长度长一些,安全性还是可以得到保障的。

最后你可千万别把秘钥搞丢了,一旦搞丢了,就意味着所有帖子的展现id需要重新计算一边,变的跟以前不一样了,搜索引擎收录的所有网页就失效了,别人外链过来的地址全都打不开,这无疑会给你的网站带来很大的损失。

原文发布于微信公众号 - 码洞(codehole)

原文发表时间:2018-01-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构师进阶

编写高质量代码的思考

最近在看《代码大全》,可以说是一本软件开发的百科全书,特别厚,但是干货也很多。平时写代码,代码规范是一个最低的要求(很多老代码连最低要求都达不到),为什么要这样...

11220
来自专栏技术专栏

慕课网Flask高级编程实战-5.书籍详情页面的构建

大多时候,我们从数据库,或者外部网络获取到的原始数据,并不能满足复杂的业务需求。业务的直观体现就是页面。

16830
来自专栏生信技能树

【生信菜鸟经】如何系统入门Perl

Perl是典型的脚本语言,短小精悍,非常容易上手,尤其适合处理文本,数据,以及系统管理。它在老一辈的生物信息学分析人员中非常流行,出于历史遗留原因大家肯定会或多...

44290
来自专栏CSDN技术头条

改变开发者编码思维的六种编程范式

译者注:本文介绍了六种编程范式,提到了不少小众语言,作者希望借此让大家更多的了解一些非主流的编程范式,进而改变对编程的看法。以下为译文: 时不时地,我会发现一些...

506100
来自专栏技术专栏

慕课网Flask高级编程实战-6.书籍详情页面的构建

大多时候,我们从数据库,或者外部网络获取到的原始数据,并不能满足复杂的业务需求。业务的直观体现就是页面。

23510
来自专栏编程

自定义HScript Expression Functions

当我需要使用Expression Functions来写表达式的时候,比如stamp函数,我试图想通过一种通用的理念站在编程的角度来表述如何使用它,而不是依靠惯...

25850
来自专栏IT派

开放Python书籍:一本短小精悍的初学者入门指南

项目地址:https://github.com/joaoventura/full-speed-python

17500
来自专栏机器之心

资源 | 开放Python书籍:一本短小精悍的初学者入门指南

选自GitHub 机器之心整理 参与:思源 如何快速熟悉 Python 编程一直是很多初学者的疑问,我们经常考虑要不要系统地从头开始啃 Python 教程,但这...

35550
来自专栏一个会写诗的程序员的博客

Java新手极简指北手册

为什么我先拿“数据结构和算法”说事捏?这玩意是写程序最最基本的东东。不管你使用 Java 还是其它的什么语言,都离不开它。而且这玩意是跨语言的,学好之后不管在哪...

14510
来自专栏数据科学与人工智能

【Python环境】python 中数据分析几个比较常用的方法

1,表头或是excel的索引如果是中文的话,输出会出错 ? 解决方法:python的版本问题!换成python3就自动解决了!当然也有其他的方法,这里就不再深究...

24680

扫码关注云+社区

领取腾讯云代金券