代码之家  ›  专栏  ›  技术社区  ›  ynn

为什么std::hash不能保证是确定性的?

  •  4
  • ynn  · 技术社区  · 6 年前

    此后,我们使用 N4140


    根据 §17.6.3.4散列要求 ,

    返回的值应仅取决于参数 k .

    [注:因此对表达式的所有求值 h(k) 具有相同的值 产生相同的结果 . 尾注]

    §20.9.12类模板哈希

    ...

    实例化 hash<Key>

    (1.1)满足哈希要求(17.6.3.4)。。。

    (1.2)。。。


    这意味着哈希值为 value (即。 hash<decltype(value)>(value) )如果重新启动程序,则可能采用不同的值。

    但为什么呢?这个限制不是C++ 11标准,而是C++ 14、C++ 17和C++ 20的标准。作为用户(不是STL开发人员),如果 std::hash 是决定性的。在实现确定性散列函数时是否存在数学困难?但是我们日常使用的哈希函数(例如,不推荐使用 md5sum 或者更安全 sha256

    0 回复  |  直到 6 年前
        1
  •  13
  •   Jaffa    6 年前

    不需要在两次运行之间确定散列函数,但是您仍然可以提供自己的散列,例如,对于您依赖的无序容器。

    至于原因, cppreference 说:

    如果 Hash 需求告诉它是确定性的,那么在不破坏需求的情况下,您将无法提供一个盐散列。

    actual explanation why

        2
  •  7
  •   ynn    6 年前

    This answer (以及其中的链接)建议 @NathanOliver 最终是有帮助的。让我举几个重要的部分。

    (来自 Issue 2291. std::hash is vulnerable to collision DoS attack )

    (来自 Do you realize that you are using random hashing? )

    开始准备,而不是立即,因为即使许可在反射器讨论中也有争议

    发行2291。std::hash易受碰撞DoS攻击 )

    在实践中,据我所知,没有实施 std::hash 实现随机散列,但您可以自己编写 my::secure_hash .

    this answer )


    附笔。

    The moment when you realize every server in the world is vulnerable .