使用Hashids替代uuid可保持原有自增ID业务

这种方法通常被称为 “双向映射”“可逆混淆”。它的核心思想是:不存储,只计算

你不需要在数据库里存额外的 UUID 字段,也不需要改表结构,只需要在接口层加一道“加解密”的工序。

核心原理:Hashids 或 自定义加解密

最简单的实现不是用复杂的 AES 加密(那样太重了),而是使用 Hashids 算法,或者简单的 异或(XOR) + Base62 转换。

  1. 对外(加密/编码):当数据从后端返回给前端或外部程序时,把自增 ID 12345 转换成类似 k4R9z 的字符串。
  2. 对内(解密/解码):当外部程序带着 k4R9z 来请求数据时,后端把它转回成数字 12345,然后用这个数字去数据库查询。

改动成本分析

改动点 1:序列化/输出层(最小侵入)

  • 做法:如果你使用的是 REST API,可以在返回 JSON 的时候,拦截 ID 字段。
  • 代码示意(伪代码)# 原来返回 {"id": 12345, "name": "test"} # 现在返回(使用hashids) {"id": hashids.encode(12345), "name": "test"} # 输出: {"id": "k4R9z", "name": "test"}
  • 优点:只需要改 API 的输出逻辑,数据库查询逻辑完全不动。

改动点 2:控制器/输入层

  • 做法:在接收到请求时(如 /api/item/k4R9z),先解码。
  • 代码示意# 接收到 id_str = "k4R9z" real_id = hashids.decode(id_str) # 转回 12345 # 后续逻辑完全不变,还是用 real_id 去查库

优缺点分析

优点:

  1. 零存储成本:不需要改数据库,不需要加字段,不需要建映射表。
  2. 改动相对少:只需要在数据进出的“网关”处处理,业务核心逻辑(增删改查)不需要大改。
  3. 防遍历效果好:外部看到的是一串乱码,无法通过 +1 来猜解其他数据。

缺点/注意事项:

  1. 防破解能力一般:Hashids 是一种混淆,不是高强度加密。如果攻击者知道你用的是 Hashids 且知道你的“盐(salt)”,是可以反向推导的。但对于防止普通爬虫和“ID预测”足够了。
  2. 分页处理:如果你用 id > last_id 分页,前端传回来的 last_id 是加密字符串,你需要先解密成数字,再拼 SQL。这需要改分页逻辑,但改动量远小于换 UUID 主键。
  3. 排序问题:加密后的字符串排序和数字排序完全不同。如果前端需要按 ID 排序,后端解密后按数字排序即可,不影响功能。

总结建议

如果你不想动数据库结构,也不想在代码里到处替换 ID 类型,使用 Hashids 这种“编码/解码”方案是性价比最高的

实施步骤:

  1. 引入 Hashids 库(几乎所有语言都有)。
  2. 写两个全局辅助函数:encode_id($num)decode_id($str)
  3. 在 API 返回数据时,把所有的 id 值过一遍 encode_id
  4. 在 API 接收参数时,把传入的 id 过一遍 decode_id

Comments

No comments yet. Why don’t you start the discussion?

发表回复