Java实现Hashids生成短且唯一的id

Hashids是一款非常小巧跨语言的开源库,可以将数字或者16进制字符串转为短且唯一不连续的字符串,Hashids是双向编码(支持encode和decode),比如,它可以将347之类的数字转换为yr8之类的字符串,也可以将yr8之类的字符串重新解码为347之类的数字。

pom.xml依赖

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

测试用例
Hashids可以自定义salt,但必须保证编码和解码过程中使用同一套salt,务必妥善保管salt。测试用例中使用的salt全部为this is my salt。

需要注意的点:

在生产环境中设置的salt要保持足够的复杂度,并且要妥善保存好salt,泄漏或者丢失salt要做的弥补工作会非常麻烦。

Hashids可以自定义编码后结果的最小长度,测试用例中统一使用11位最小编码结果长度。11位最小编码长度,意味着不同的输入得到的结果长度是可能超过11位的。

org.hashids >> hashids >> 1.0.3 在编码和解码过程中严格区别大小写。

import cn.hutool.core.util.HexUtil;
import org.hashids.Hashids;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.stream.Collectors;
public class HashidsTest {
    static final String SALT = "your salt";
    static final int LENGTH = 32;

    public String arrstoString(long[] arrs){
        return Arrays.stream(arrs).boxed().map(Object::toString).reduce("",String::concat);
    }
    /**
     * 编码long类型的可变参数为字符串
     */
    @Test
    void test_hashids_encode_method() {
        Hashids hashids = new Hashids(SALT,LENGTH);
        String encryptString = hashids.encode(123L);
        System.out.println(encryptString); // BzpXovn6w1yeV7Y7ROKlg9OEQr8GMaD5
    }

    /**
     * 解码字符串为Long类型数组
     */
    @Test
    void test_hashids_decode_method() {
        Hashids hashids = new Hashids(SALT, LENGTH);
        long[] decrypedNumbers = hashids.decode("BzpXovn6w1yeV7Y7ROKlg9OEQr8GMaD5");
        System.out.println(arrstoString(decrypedNumbers)); // 347
        //必须将普通数组 boxed才能 在 map 里面 toString
        System.out.println(Arrays.stream(decrypedNumbers).boxed().map(i -> i.toString()).collect(Collectors.joining(""))); // 347
    }

    /**
     * 编码16进制字符串为Hashids字符串
     */
    @Test
    void test_hashids_encodeHex_method() {
        Hashids hashids = new Hashids(SALT, LENGTH);
        String encryptString = hashids.encodeHex(HexUtil.encodeHexStr("123"));
        System.out.println(encryptString); // Vng6Gl9owp0qYk4L7A13ObLPMR1JEXAx
    }

    /**
     * 解码Hashids字符串为16进制字符串
     */
    @Test
    void test_hashids_decodeHex_method() {
        Hashids hashids = new Hashids(SALT, LENGTH);
        String decrypedNumbers = hashids.decodeHex("Vng6Gl9owp0qYk4L7A13ObLPMR1JEXAx");

        System.out.println(cn.hutool.core.util.HexUtil.decodeHexStr(decrypedNumbers)); // 123
    }

    /**
     * 默认映射字母表为:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
     * 自定义的字母表中的字符至少应含有16个字符
     */
    @Test
    void test_hashids_costom_alphabet_by_Constructor() {
        final String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-";

        Hashids hashids = new Hashids(SALT, LENGTH, ALPHABET);
        String encryptString = hashids.encode(123L);

        System.out.println(encryptString); // 0kL2_Omoz5lBe7wlxRMxqbQrvdnZXRAN

        long[] decrypedNumbers = hashids.decode("0kL2_Omoz5lBe7wlxRMxqbQrvdnZXRAN");

        System.out.println(arrstoString(decrypedNumbers));

    }


}

注:如果编码和解码过程中使用的salt不一致,则long[]为空数组

参考:
Hashids生成短且唯一的id
Hashids 原理及实现

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值