【问题标题】:Is it wrong to use a hash for a unique ID?使用哈希作为唯一 ID 是错误的吗?
【发布时间】:2013-04-27 11:03:58
【问题描述】:

我想在可能永远不会超过 10,000 条记录的数据库表中使用 PHP 生成的唯一 ID。我不希望创建时间可见或使用纯数值,所以我正在使用:

sha1(uniqid(mt_rand(), true))

对唯一 ID 使用哈希是错误的吗?不是所有的哈希都会导致冲突吗?或者在这种情况下不应该考虑这些可能性?

还有一点:如果要散列的字符数小于 sha1 散列中的字符数,它不总是唯一的吗?

【问题讨论】:

  • 不,没有错。使用将时间戳传递给 sha1 会很好。
  • 这可能是个好读物:: stackoverflow.com/questions/2768191/…
  • 为什么要创建自己的唯一 ID?你的数据库不支持自增主键吗?这通常被认为是在数据库标识符上拥有唯一 ID 的方式。
  • @Patrick M 我不希望这些 ID 有任何意义。
  • 这样做的一个原因是为了防止黑客在您的应用程序中找到一个 http GET 端点,并简单地使用这些顺序自动递增的键来浏览您的数据库。几年前发生在 AT&T 上的事情相当有名,抱歉,找不到它的链接,但我每次设计系统时都会记得它。因此,将端点 /customer/5 转换为 /customer/dhftrt5sahjgertgjwygad 是一个明显的优势 - 否则会真的如此简单地被黑客入侵。

标签: php hash


【解决方案1】:

如果您有 2 个密钥,理论上最好的情况是 2 中 1 ^ X 的冲突概率,其中 X 是您的哈希算法中的位数。 “最佳情况”,因为输入通常是不使用完整字符集的 ASCII,加上散列函数分布不完美,因此它们会比现实生活中的理论最大值更频繁地发生冲突。

回答你的最后一个问题:

还有一点:如果要散列的字符数小于 sha1 哈希中的字符数,它不总是唯一的吗?

是的,没错。但是您会遇到另一个问题,即生成该大小的唯一键。最简单的方法通常是校验和,因此只需选择一个足够大的摘要,以使碰撞空间足够小,让您感到舒适。

正如@wayne 建议的那样,一种流行的方法是将microtime() 连接到您的随机盐(和base64_encode 以提高熵)。

【讨论】:

  • 谢谢,应该是:sha1(base64_encode(microtime().uniqid(mt_rand(), true)))
  • @texelate 这将是一个很好的起点。有关盐渍的更多信息,请参阅此页面点,尤其是 1+2:blog.ircmaxell.com/2012/12/seven-ways-to-screw-up-bcrypt.html
  • 谢谢。我需要它是为了唯一性而不是安全性,但仍然是非常有用的阅读。
【解决方案2】:

如果两个结局相同,那该有多可怕?墨菲定律适用 - 如果一百万比一,甚至 100,000:1 的机会是可以接受的,那就继续吧!真正的机会要小得多——但如果发生这种情况你的系统会爆炸,那么必须首先解决你的设计缺陷。然后充满信心地继续前进。

以下是关于概率的真正含义的问题/答案:Probability of SHA1 Collisions

【讨论】:

    【解决方案3】:

    使用 sha1(time()) 代替,然后您消除重复哈希的随机可能性,只要时间可以表示为比 sha1 哈希更短。 (可能比你找到一个工作的 php 解析器要长;))

    【讨论】:

    • then you remove the random possibility of a repeating hash .. 除非您实例化超过 1 个对象 pr。第二 - 恕我直言,这不是很多。我建议不要只使用时间戳作为唯一键的输入
    【解决方案4】:

    计算机随机实际上并不是随机的,你知道吗? 假设您在 Unix 环境中,您可以从计算机获得的唯一真正随机来自 /dev/random,但这是一个阻塞操作,取决于用户交互,例如移动鼠标或在键盘上打字。从/dev/urandom 读取不太安全,但它可能比仅使用 ASCII 字符更好,并且可以立即响应。

    【讨论】:

      【解决方案5】:

      sha1($ipAddress.time()) 导致任何人不可能同时使用相同的IP地址

      【讨论】:

        猜你喜欢
        • 2014-02-17
        • 2011-02-15
        • 2016-12-10
        • 1970-01-01
        • 2013-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-27
        相关资源
        最近更新 更多