轻量级哈希扰动工具:Hashids,快速上手

前言:

紧接上文,在生成短链接或ID的时候,号段模式兼顾SnowflakeUUID 的性能与安全,数据库自增的简洁,但是面临核心痛点:

  • ID 是纯数字,单调递增,极易被猜测和遍历
  • ID 长度随业务增长而变长

这时候,Hashids 就登场了------它不是加密算法,而是一个可逆的、带盐的 ID 混淆工具,专为解决这类问题而生。本文将带你深入理解这一方案的核心思想,并手把手实现一个生产级的短码生成服务。


一、Hashids 是什么?它如何工作?

Hashids 的核心思想很简单:把一个或多个整数,通过加盐和自定义字符集,转换成一段看似随机的字符串

关键特性:

  • 可逆:知道 salt 和算法,就能从字符串还原出原始 ID
  • 加盐混淆:相同的 ID,在不同 salt 下生成完全不同结果
  • 自定义字符集 :可排除易混淆字符(如 0/O/I/l),实现 Base58 风格
  • 支持多 ID 编码 :可将多个数字一起编码(如 [user_id, item_id]
  • 跨语言兼容:Java、Python、JavaScript 等实现行为一致

示例:

java 复制代码
Hashids hashids = new Hashids("my-secret-salt", 4, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
String shortCode = hashids.encode(12345); // 输出如 "aB3k"
long[] decoded = hashids.decode("aB3k");  // 还原为 [12345]

注意:Hashids 不是加密 它的安全性完全依赖于 salt 密钥的保密性。


三、为什么选择 Base58 字符集?

默认的 Hashids 使用 Base62(a-zA-Z0-9),但我们更推荐 Base58,去除混淆视觉的lIO0,优化用户使用体验。


四、完整架构:号段 + Hashids + Base58

我们的目标是:用高性能的方式生成安全、美观、固定最小长度的短码

架构流程:

  1. 号段模式:从数据库批量获取唯一数字 ID
  2. Hashids 编码:将 ID 转为至少 4 位的 Base58 字符串
  3. 对外暴露短码:用户看到的是不可预测的字符串,而非原始 ID
  4. 解析时反向 decode:通过短码还原 ID,查询数据库

整个过程无随机、无冲突、高性能、防遍历。


五、实战:Spring Boot 实现

1. 添加依赖

xml 复制代码
<dependency>
    <groupId>org.hashids</groupId>
    <artifactId>hashids</artifactId>
    <version>1.0.3</version>
</dependency>

2. YAML 配置

yaml 复制代码
app:
  hashids:
    salt: "${HASHIDS_SALT:default-fallback}" 
    min-length: 4
    alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

3. 配置类

java 复制代码
@ConfigurationProperties(prefix = "app.hashids")
@Component
public class HashidsProperties {
    private String salt = "default";
    private int minLength = 4;
    private String alphabet = "123456789..."; // Base58
    // getters & setters
}

@Configuration
public class HashidsConfig {
    private final HashidsProperties props;
    public HashidsConfig(HashidsProperties props) {
   this.props = props;
    }

    @Bean
   public Hashids hashids() {
        return new Hashids(props.getSalt(), props.getMinLength(), props.getAlphabet());
    }
}

4. 短码服务

java 复制代码
//示例代码,只展示最精简部分
@Service
public class ShortCodeService {
    private final Hashids hashids;
    private final DbSegmentIdGenerator segmentIdGenerator; // 你的号段实现

    public ShortCodeService(Hashids hashids, DbSegmentIdGenerator segmentIdGenerator) {
        this.hashids = hashids;
        this.segmentIdGenerator = segmentIdGenerator;

    }
    // 生成短码
    public String generate(String bizTag) {
        long id = segmentIdGenerator.nextId(bizTag);
        return hashids.encode(id);
    }
    // 解析短码(用于调试或内部查询)
    public long decodeToId(String shortCode) {
        long[] ids = hashids.decode(shortCode);
        if (ids.length == 0) throw new IllegalArgumentException("Invalid short code");
        return ids[0];
    }
}

六、总结:

Hashids 提供了一种简便的方法来创建短小而独特的字符串标识符,非常适合那些不需要高度安全保障但又希望能隐藏实际数值的应用场景,在搭配号段模式、的有序id生成短链接时有起效。当你需要:

  • 把数字 ID 变成短字符串
  • 隐藏内部结构
  • 防止遍历猜测
  • 节省存储(无需映射表)

------那么,Hashids 就是一个简单、高效、优雅的选择。

相关推荐
玛丽莲茼蒿18 小时前
javaSE 集合框架(五)——java 8新品Stream类
java·开发语言
程序员小假18 小时前
设计一个支持万人同时抢购商品的秒杀系统?
java·后端
L***d67018 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端
C雨后彩虹18 小时前
竖直四子棋
java·数据结构·算法·华为·面试
疾风sxp18 小时前
nl2sql技术实现自动sql生成之langchain4j SqlDatabaseContentRetriever
java·人工智能·langchain4j
一勺菠萝丶19 小时前
PDF24 转图片出现“中间横线”的根本原因与终极解决方案(DPI 原理详解)
java
姓蔡小朋友19 小时前
Unsafe类
java
一只专注api接口开发的技术猿19 小时前
如何处理淘宝 API 的请求限流与数据缓存策略
java·大数据·开发语言·数据库·spring
荒诞硬汉19 小时前
对象数组.
java·数据结构
期待のcode19 小时前
Java虚拟机的非堆内存
java·开发语言·jvm