8

I have some random test parameters for which I need to calculate a hash to detect if I ran with same parameters. I might run the test using the same source recompiled at a different time or run on a different machine.

Even so I want to detect whether the same parameters were used for the run. Does std::hash give the same result for the same input for different compiled builds and different machines?

e.g.

std::hash<string>{}("TestcaseParamVal0.7Param0.4");

Will this always be a unique number?

curiousguy
  • 8,038
  • 2
  • 40
  • 58

1 Answers1

12

No, std::hash does not guarantee that the result will be the same across computers, builds, or even executions of the same build on the same computer. Your only guarantee is that during one execution, objects that are equal have the same hash. (There is, of course, no guarantee that objects that are unequal have different hashes.)

Some implementations go out of their way to change hash results between executions, as it mitigates denial of service risks due to the poor performance of hash tables in the presence of many keys with the same hash. This is explicitly allowed by the standard, which only guarantees that results are consistent for the duration of the program.

If you need repeatability between executions and machines, you can't use std::hash and must roll out your own equivalent.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • For better protection against DoS, use a secure cryptographic nonce (some call it "salt") in a secure cryptographic hashing function: nobody else (but the spyware with full read access on the computer running the server) would be able to produce intentional hash collisions. (For a secure hash with a nonce, even good old MD5 will do.) OTOH, such hash functions are much slower than a non cryptographic hash. – curiousguy Jul 03 '18 at 15:10
  • 1
    IMO, if it’s that important to you, you should be using a container with predictable performance (like std::map) instead of computing an expensive hash and only keeping 8 bytes. – zneak Jul 03 '18 at 15:15
  • Good idea, but it isn't a drop-in replacement: the interface is different. What if a type comes with just an equality comparison and a hash function? – curiousguy Jul 03 '18 at 16:05
  • 1
    You’ll have to create your own comparator, of course, which isn’t terribly worse than writing your own hash function. Using a cryptographic hash for things that aren’t blobs of data isn’t necessarily straightforward either. – zneak Jul 03 '18 at 16:33
  • 1
    Yes, unless there is a serialization function of the data, that is guaranteed to be "stable", purely applicative (two equal object values get the same serialization), you are right. And that serialization might be costly too! – curiousguy Jul 03 '18 at 16:44
  • @zneak What is considered an execution? Does two instance of the same std::hash required to generate the same result if the the program never restart? – W.H Mar 11 '21 at 00:59
  • @zneak Do you any good hash-functions to use instead of std::hash, if I want to get same results between multiple runs ? – Nisal Dissanayake Jul 08 '21 at 10:23