In real-world programming, we frequently need to compute hash codes for complicated objects. The main desired properties are that the values should
- be deterministic and
- have few collisions.
Let's assume we have access to robust hashing for basic data types such as integers, strings, etc. How do we combine multiple such hash codes to a single one, say for an array or a struct with several properties?
I immediately went for XOR-ing all "child" codes, figuring that the "spread" of the original hash function should be maintained, roughly. Apparently, I'm not alone.
However, if you google around, you find other approaches.
- Here an answerer proposes adding hash codes after perturbing them by some multiplication.
- This asker uses XOR but multiplies the individual codes with some numbers, apparently consciously choosing "large" primes.
- Here, the author states that "[things] have low values (favour the lower bits), so they should be combined with a multiplication to spread them across a wider bit range of the hash code".
The reasons given, if any, seem vacuous to me. Does multiplying already "random" values with a (small) constant really serve any purpose? Does it matter if the factor is a prime (which everybody seems to assume)?