Hashids

什么是hasids

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

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

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

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

然后还可以设置映射字典。默认是base64[26+26+10]编码,如果你不喜欢大小写敏感,可以改成base36[26+10]编码。

算法的实现原理

算法的作者不保证安全性,不建议将hashids用在安全领域

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

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

hashids满足第1和第3条,正向计算hash很快,hash值完全没有碰撞,保证了唯一性。如果知道salt值,还可以逆向通过hash值计算出原值。那第2条是否满足取决于你的salt秘钥有多容易被攻击者拿到。

java 的实现

github上java版的hashids实现 https://github.com/10cella/hashids-java

引用依赖

1
2
3
4
5
<dependency>
<groupId>org.hashids</groupId>
<artifactId>hashids</artifactId>
<version>1.0.3</version>
</dependency>

使用示例

1
2
Hashids hashids = new Hashids("this is my salt");
String hash = hashids.encode(12345L);

参考