防碰撞哈希类标识符

Collision-proof hash-like identificator

我需要生成一个 6 个字符长度(字母和数字)的 ID 来标识 SaaS 工作区(每个用户唯一)。当然,我可以只使用数字,但它不应该提供任何关于真实工作空间编号的清晰愿景(对于最终用户)。

因此,即使对于 id 1,它也应该是 6 个字符长度,类似于 fX8gz6 并且完全可解码为 1000001 或我可以解析为真实工作区 id 的东西。当然还要防撞。

最好的方法是什么?

这类似于亚马逊用于其云资产的内容,但它使用 8 个字符。其实8个字符比较合适,因为它是6个二进制字节Base64编码后的输出范围。

假设您可以灵活地使用 8 个字符。在最初的问题中,你说了 6 个字符,但再次假设。这是一个可能的方案:

  1. Unsigned Int32 为您的资产编号,可能是自动递增方式。称之为 real-id。将此真实 ID 用于所有内部用途。
  2. 当你需要显示它时,按照这样的操作:
  3. 将您的整数转换为 4 个二进制字节。每种语言都有从整数中提取字节的库,反之亦然。称之为 real-id-bytes
  4. 取一个两字节的随机数。同样,您可以使用库生成精确的 16 位随机数。您可以使用加密随机数生成器以获得更好的结果,或者普通的 rand 就可以了。称之为 rand-bytes
  5. 获得6字节display-id-bytes= array-concat(rand-bytes, real-id-bytes)
  6. 获得display-id= Base64(display-id-bytes)。这正好是 8 个字符长,混合了小写、大写和数字。

现在你有一个看似随机的 8 个字符 display-id 可以映射到 real-id。要转换回来:

  1. 取8个字符display-id
  2. display-id-bytes= Base64Decode(display-id)
  3. real-id-bytes= Discard-the-2-random-bytes-from(display-id-bytes)
  4. real-id= fromBytesToInt32(real-id-bytes)

简单。现在,如果您真的不能使用 8 个字符的显示 ID,那么您必须开发一些自定义的 base-64,例如算法。您也可以将自己限制为仅 1 个随机字节。另请注意,这只是一种编码方案,而不是加密方案。因此,任何了解您的方案的人都可以有效地 break/decode ID。您需要决定这是否可以接受。如果没有,那么我想您必须进行某种形式的加密。无论如何,6个字符肯定是远远不够的。