本文共 1499 字,大约阅读时间需要 4 分钟。
爬虫与反爬是一对相生相克的死对头,道高一丈魔高一尺。作为爬虫的一方,如果知道了某个站点的数据自增ID,那么就能轻而易举把整个站点都爬下来。是不是有点耸人听闻,你去看很多大站例如油管、P站等,他们都不会轻易把业务的自增ID暴露出来,而是用一种可逆的hash字符串替代。
最常用的ID混淆就是Hashids。Hashids是一个小型的开放源代码库,可以将数字生成很短的、唯一的、非顺序的字符ID。例如可以数字347
转换为 “yr8” 字符串,你还可以将字符串ID进行解码恢复成数字。
下面就来看看咋使用的
pip install hashids
首选初始化一个 hashids 实例
from hashids import Hashidshashids = Hashids()
>>> id = hashids.encode(1)>>> id'jR'>>> hashids.encode(123)'Mj3'>>> hashids.encode(1234)'1lj'>>> hashids.encode(12345)'j0gW'>>> hashids.encode(123454)'v27AV'
生成的字符ID长度与和数值大小有关。
>>> num = hashids.decode('jR')>>> num(1,)>>> hashids.decode("Mj3")(123,)>>> hashids.decode("1lj")(1234,)>>> hashids.decode("j0gW")(12345,)>>> hashids.decode("v27AV")(123454,)
解码后返回时一个元组。
如果你解码一个随机的字符串ID,不一定能恢复成数字,此时会返回空元组。
>>> hashids.decode("werwer")()
因为hashid可逆,所以别人拿到字符串后也能根据字符串ID反推出数字,因此,为了避免别人猜出原始数字ID,我们在编码的时候可以指定盐值。理论上,只要盐值不被泄露,被破解的难度就加大了很多。
初始化 hashids时候,可以指定盐值
>>> hashids = Hashids(salt="XXXX")>>> hashids.encode(123)'1LY'>>> hashids.decode("1LY")(123,)
同样的数字使用不同的盐值编码得到的字符串是不同的,别人就无法猜出原始ID是多少了。
默认情况下,数字越小,编码生成的字符串也比较短,为了将不同大小的数值转换为统一长度的字符串,在初始化hashids的时候,可以指定hash的最小长度
>>> hashids = Hashids(salt="XXXX", min_length=10)>>> hashids.encode(123)'PyNd1LYK3G'
如果你不希望hash中有大写字母,那么可以在初始化的时候,指定hash字符串的范围,例如我们可以指定为所有的小写字母
>>> hashids = Hashids(alphabet="abcdefghigklmopkrst")>>> hashids.encode(123)'ggdo'
需要注意的时候,alphabet至少要指定16个以上的不同字符。
hashids 简单却实用,是避免业务ID外露办法之一。
今日思考题
你知道hashids的实现原理是什么吗?留言区第一个答对的奖励1本算法书。
推荐阅读
关注公众号,一起学习Python
转载地址:http://hrqwb.baihongyu.com/