防碰撞类似哈希的识别器

时间:2015-02-25 04:32:50

标签: hash saas url-shortener

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

因此即使对于id 1,它应该是6个字符长度,类似fX8gz6并且可以完全解码为1000001或者我可以解析为实际工作空间id的东西。当然,它必须是防碰撞的。

最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

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

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

  1. Unsigned Int32为您的资产编号,可能会自动增加时尚。称之为real-id。将此real-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个字符长,混合了小写,大写和数字。
  7. 现在你有一个看似随机的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)
    5. 简单。现在,如果你真的不能去8-char display-id那么你必须开发一些自定义base-64像algo。您也可以将自己限制为仅1个随机字节。另请注意,这只是一种编码方案,而不是加密方案。因此,任何了解您的方案的人都可以有效地破解/解码ID。你需要决定这是否可以接受。如果没有,那么我猜你必须做某种形式的加密。无论如何,6个字符肯定是不够的。