防碰撞哈希类标识符
Collision-proof hash-like identificator
我需要生成一个 6 个字符长度(字母和数字)的 ID 来标识 SaaS 工作区(每个用户唯一)。当然,我可以只使用数字,但它不应该提供任何关于真实工作空间编号的清晰愿景(对于最终用户)。
因此,即使对于 id 1,它也应该是 6 个字符长度,类似于 fX8gz6
并且完全可解码为 1
或 000001
或我可以解析为真实工作区 id 的东西。当然还要防撞。
最好的方法是什么?
这类似于亚马逊用于其云资产的内容,但它使用 8 个字符。其实8个字符比较合适,因为它是6个二进制字节Base64编码后的输出范围。
假设您可以灵活地使用 8 个字符。在最初的问题中,你说了 6 个字符,但再次假设。这是一个可能的方案:
- 以
Unsigned Int32
为您的资产编号,可能是自动递增方式。称之为 real-id
。将此真实 ID 用于所有内部用途。
- 当你需要显示它时,按照这样的操作:
- 将您的整数转换为 4 个二进制字节。每种语言都有从整数中提取字节的库,反之亦然。称之为
real-id-bytes
- 取一个两字节的随机数。同样,您可以使用库生成精确的 16 位随机数。您可以使用加密随机数生成器以获得更好的结果,或者普通的
rand
就可以了。称之为 rand-bytes
- 获得6字节
display-id-bytes
= array-concat(rand-bytes, real-id-bytes)
- 获得
display-id
= Base64(display-id-bytes)
。这正好是 8 个字符长,混合了小写、大写和数字。
现在你有一个看似随机的 8 个字符 display-id
可以映射到 real-id
。要转换回来:
- 取8个字符
display-id
display-id-bytes
= Base64Decode(display-id)
real-id-bytes
= Discard-the-2-random-bytes-from(display-id-bytes)
real-id
= fromBytesToInt32(real-id-bytes)
简单。现在,如果您真的不能使用 8 个字符的显示 ID,那么您必须开发一些自定义的 base-64,例如算法。您也可以将自己限制为仅 1 个随机字节。另请注意,这只是一种编码方案,而不是加密方案。因此,任何了解您的方案的人都可以有效地 break/decode ID。您需要决定这是否可以接受。如果没有,那么我想您必须进行某种形式的加密。无论如何,6个字符肯定是远远不够的。
我需要生成一个 6 个字符长度(字母和数字)的 ID 来标识 SaaS 工作区(每个用户唯一)。当然,我可以只使用数字,但它不应该提供任何关于真实工作空间编号的清晰愿景(对于最终用户)。
因此,即使对于 id 1,它也应该是 6 个字符长度,类似于 fX8gz6
并且完全可解码为 1
或 000001
或我可以解析为真实工作区 id 的东西。当然还要防撞。
最好的方法是什么?
这类似于亚马逊用于其云资产的内容,但它使用 8 个字符。其实8个字符比较合适,因为它是6个二进制字节Base64编码后的输出范围。
假设您可以灵活地使用 8 个字符。在最初的问题中,你说了 6 个字符,但再次假设。这是一个可能的方案:
- 以
Unsigned Int32
为您的资产编号,可能是自动递增方式。称之为real-id
。将此真实 ID 用于所有内部用途。 - 当你需要显示它时,按照这样的操作:
- 将您的整数转换为 4 个二进制字节。每种语言都有从整数中提取字节的库,反之亦然。称之为
real-id-bytes
- 取一个两字节的随机数。同样,您可以使用库生成精确的 16 位随机数。您可以使用加密随机数生成器以获得更好的结果,或者普通的
rand
就可以了。称之为rand-bytes
- 获得6字节
display-id-bytes
= array-concat(rand-bytes, real-id-bytes)
- 获得
display-id
= Base64(display-id-bytes)
。这正好是 8 个字符长,混合了小写、大写和数字。
现在你有一个看似随机的 8 个字符 display-id
可以映射到 real-id
。要转换回来:
- 取8个字符
display-id
display-id-bytes
= Base64Decode(display-id)
real-id-bytes
= Discard-the-2-random-bytes-from(display-id-bytes)
real-id
= fromBytesToInt32(real-id-bytes)
简单。现在,如果您真的不能使用 8 个字符的显示 ID,那么您必须开发一些自定义的 base-64,例如算法。您也可以将自己限制为仅 1 个随机字节。另请注意,这只是一种编码方案,而不是加密方案。因此,任何了解您的方案的人都可以有效地 break/decode ID。您需要决定这是否可以接受。如果没有,那么我想您必须进行某种形式的加密。无论如何,6个字符肯定是远远不够的。