介绍一款用于搞乱数据库ID的开源Python库

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

拿论坛来讲,通常帖子在数据库里的id都是顺序递增的,可是你可能不想在url上直接把id暴露出来,以避免爬虫直接遍历id爬取你的内容,给你带来损失。那如今你就可使用Hashids把这个id搞乱,让它失去顺序性,没法直接遍历,这样就能够直接提升了爬虫的门槛。著名的Youtube网站就是这么作的。算法

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

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

hashids须要提供一个salt值,至关于编解码的私钥,别人不知道你的私钥,就没法编码出对应的帖子的展示key,也没法经过url上的展示key解码出对应的帖子id。因此想直接遍历你的帖子服务那就作不到了。json

如今咱们试试随便提供字符串,对它进行解码会怎样安全

咱们看到这些字符串都是非法,因此hashids没法解码出对应的整数。网站

下面咱们对一段连续整数进行编码搜索引擎

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

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

咱们发现能够设置编码后字符串的最小长度。若是你不设置这个最小长度,对于一个从0开始的自增id,编码出来的字符串长度一开始只有2位,可是随着id的增加,编码后的长度也愈来愈大,可是最终这个长度值愈来愈稳定,由于位数越大能够表达的数值就越多。若是咱们设置了这个最小长度,在id没有恐怖的快速增加的状况下,那么编码出的长度一开始就是很是稳定的。3d

而后咱们还能够设置映射字典。默认是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须要从新计算一边,变的跟之前不同了,搜索引擎收录的全部网页就失效了,别人外链过来的地址全都打不开,这无疑会给你的网站带来很大的损失。

阅读相关文章,关注公众号「码洞

相关文章
相关标签/搜索