Далее мы используем N4140 (C ++ 14 Standard).
В соответствии с § 17.6.3.4 Хеш-требованиями ,
Возвращаемое значение должно зависеть только от аргумента
k
для продолжительности программы .[Примечание: Таким образом, все вычисления выражения
h(k)
с одинаковым значением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
), являются детерминированными. Есть ли проблема эффективности?
Ответы:
Нет необходимости, чтобы хэш-функция была детерминированной между запусками, но вы все равно можете предоставить свой собственный хэш, например, для неупорядоченных контейнеров, если вы полагаетесь на такое поведение.
Что касается того, почему cppreference говорит:
Если
Hash
требования говорят о том, что он является детерминированным, вы не сможете предоставить соленый хеш, не нарушая требования.Вот фактическое объяснение, почему
источник
Этот ответ (и ссылки в нем), предложенные @NathanOliver, в конечном итоге полезны. Позвольте мне привести важные части.
PS
Я просто погуглил «хэш-таблицу dos» и нашел информативную страницу: момент, когда вы понимаете, что каждый сервер в мире уязвим .
источник