Does std::hash give same result for same input for different compiled builds and different machines?
Asked Answered
C

1

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?

Curnin answered 3/7, 2018 at 0:55 Comment(3)
added example codeCurnin
@Oighea, not all questions need code, and this one in particular doesn't seem like it needs any to be clear and answerable.Judyjudye
Fact is, the original form is poorly formatted and paragraphed. That is why he got reminded.Pianola
J
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.

Judyjudye answered 3/7, 2018 at 1:15 Comment(7)
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.Rotl
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.Judyjudye
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?Rotl
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.Judyjudye
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!Rotl
@Judyjudye What is considered an execution? Does two instance of the same std::hash<T> required to generate the same result if the the program never restart?Condition
@Judyjudye Do you any good hash-functions to use instead of std::hash, if I want to get same results between multiple runs ?Frontwards

© 2022 - 2024 — McMap. All rights reserved.