Re:String.hashCode() is plenty unique
by cm2187 on Saturday August 11, 2018 @04:46AM
(#17738951)
Actually is any hashing algorithm guaranteeing uniqueness? Of course it is theoretically impossible to guarantee that (pigeonhole principle) but even practically, can a collision occur on sha256 in real use? I understand the hash is designed so that it is theoretically difficult to manufacture a collision but surely a collision could occur in real life?
[ Parent
| on HN ]
Suppose there are 100 billion computers in the world, including phones, smart watches, toasters, etc. Suppose each of those can perform at the level of a state of the art specialized mining ASIC, 10 million million hashes per second, and they've all been generating 256-bit hashes constantly for 30 years, or a billion seconds.
Suppose further that sha256 is pretty good and the probability of a collision is close to that of random chance.
Then there have been 1e33 sha256 hashes generated ever. Looking at the probability table on Wikipedia for the birthday problem [0] and the row for 256 bits, interpolating it gives a probability of 1e-10 that there has been a collision.
So there would be a chance of one in ten billion that some two hashes have collided over the last 30 years. Your piece of toast, perhaps, and my bitcoin digest.
I think for practical purposes we're pretty safe.
Impressively, my Facebook interviewer did not recognize validity of nearly identical explanation for using sha256 hashes instead of full strings as a key for purpose of counting stack traces.
I think you are assuming it has a perfectly uniform distribution.
Yes, that's what I meant by saying sha256 is at least "pretty good" as a hash function. Which is not at all proven, but one of the reasons sha256 is popular is that it looks like it should be close to uniform.
Perfect hash functions guarantee no collisions. Of course they have other limitations, so you have to pick some tradeoffs.
I'm pretty sure, as the parent mentioned, that theoretic collisionness is impossible with |input-domaim| > |output-domain| bc of the pigeonhole principle. Especially so when input has no maximum size.
However perfect it is, it can only guarantee no collisions if the size of the strings you're hashing is equal or lower than the hash size.
In this house, we obey the pigeonhole principle.
It can do better, if the input is not "every possible string." A perfect hash of the strings representing 32-bit unsigned integers can compress strings up to 10 bytes long into 4 bytes of data.