乐趣区

hashids插件库解决序列id易泄露易推导的问题

ID 管理方式的介绍

  1. 32 位 UUID 转 Base64 编码,快速的 id 生成方案,问题在于编码可读性差,长度太长,查询效率低。
  2. 自增序列类型数字主键,完全的自动增长,容易被判断推导出其他的主键值。本方案就是使用 hashids 解决 id 易推导的问题,并且 id 在数据量不大的情况下也不大。
  3. 根据时间戳生成 ID。如果你能承受一定程度的碰撞,你可以编写一个动态建立的 id。使用计数器(如果有的话)+ 时间戳(以毫秒为单位)+ 某个系统值(IP 地址或某个机器 ID)+ 随机整数。许多大公司都采用这种方法,因为它在分布式系统中运行良好。这些 ID 是彼此独立生成的,碰撞风险非常小,可以忽略不计。一般可能需要依赖 redis 等服务。

Hashids 是一个小型开源库,可以从数字中生成简短,独特,非顺序的 ID。

它将像 347 这样的数字转换为像“yr8”这样的字符串,或者像 [27,986] 这样的数字数组转换为“3kTMd”。这在将多个参数捆绑到一个或简单地将它们用作短 UID 时非常有用。
注意 Hashids 不是真正的加密算法,Hashids 的工作方式与整数转换为十六进制的方式类似,但有一些例外:
1. 字母表不是 base16,而是默认的 base base62。
2. 字母表也根据盐进行洗牌。
 Hashids 一种混淆数字的算法,与普通意义的 hash(类似 md5 等的单向散列算法)不是一个意思。Hashids 是可以根据盐值反向解码的。因为盐值的存在,可以一定程度的防止破解。
特征
1. 从数字(正数和零)创建短唯一 ID。
2. 允许自定义字母和盐 – 所以 ID 只有你自己。
3. 增量输入被破坏以保持不可思议。
4. 代码很小(约 350 行),速度快,不依赖于外部库。


代码示例

Hashid 库可以支持各种语言,例如 javascript 或者 java。以下以 java 为例。

import org.hashids.Hashids;
public class HashIds {public static void main(String[] args) {Hashids hashids = new Hashids("this is my salt");
        long a=12345678L;
        System.err.println("1 待转码的数字:"+a);
        String hash = hashids.encode(a);
        System.err.println("1 转码结果:"+hash);
        hashids = new Hashids("this is my salt");// 用加密的盐解密
        long[] numbers = hashids.decode(hash);
        System.err.println("1 解码结果:"+numbers[0]);// 其可以加密数组,默认相当于数组
        
        
        long b1=100L;
        long b2=200L;
        Hashids hashids2 = new Hashids("this is my salt", 8);// 8 代表最低转码位数,防止位数太少
        System.out.println("2 待转码的数字组合:"+b1+","+b2);
        String hash2 = hashids2.encode(b1,b2);
        System.out.println("2 转码结果:"+hash2);
         hashids2= new Hashids("this is my salt", 8);
        long[] numbers2 = hashids2.decode(hash2);
        System.out.println("2 解码结果:"+numbers2[0]+","+numbers2[1]);
    }
}

如果是 maven 程序,可以在 pom 这样引入

<dependency>
   <groupId>org.hashids</groupId>
   <artifactId>hashids</artifactId>
   <version>1.0.3</version>
</dependency>

退出移动版