The ubiquity of decent hashes also means that they're commonly used for situations where they're not wholly appropriate. I've frequently encountered non-cryptographic hashes being used for fixed sized integer maps or iterated.
Even non-cryptographic functions can benefit from the same kinds of threat modeling and carefully attention to selection criteria common in crypto. The risk for failing is that you end up with something as catastrophically flawed as boost's hash_combine [0].
on one hand i can see how it's going to break stuff (and I see they've changed it! []). on the other hand... mind talking a bit more about how it did break things?
Let's call the old combine function C. How long can you combine things C(C(C(C(a, b), c), d), e)... until you get a collision? Experimentally, it averaged around 2^14 iterations and I had examples with 7. The issue was that I found this code deep in the bowels of a system controlling heavy machinery such that a collision potentially meant life altering consequences for someone.
I wasn't aware boost had changed it, but the solution I settled on was essentially identical to what boost came to here. There's some further issues with that system in that the mixing functions aren't ideal for all bitlengths T. The way they're using it here is safe, but it annoyed me enough to devise a class of mixing functions with provably max length periods for all sizes T (at the cost of some mixing quality). Haven't published that crate yet because I'm not sure who else would want it.
Even non-cryptographic functions can benefit from the same kinds of threat modeling and carefully attention to selection criteria common in crypto. The risk for failing is that you end up with something as catastrophically flawed as boost's hash_combine [0].
[0] https://www.boost.org/doc/libs/1_70_0/doc/html/hash/referenc...