转载

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>
原文  https://segmentfault.com/a/1190000019542788
正文到此结束
Loading...