Probability of 64bit Hash Code Collisions

后端 未结 4 986
天涯浪人
天涯浪人 2021-02-04 07:30

The book Numerical Recipes offers a method to calculate 64bit hash codes in order to reduce the number of collisions.

The algorithm is shown at http://www.javamex.com/tu

相关标签:
4条回答
  • 2021-02-04 07:56

    Is there a formula to estimate the probability of collisions taking into account the so-called Birthday Paradox?

    Using the Birthday Paradox formula simply tells you at what point you need to start worrying about a collision happening. This is at around Sqrt[n] where n is the total number of possible hash values. In this case n = 2^64 so the Birthday Paradox formula tells you that as long as the number of keys is significantly less than Sqrt[n] = Sqrt[2^64] = 2^32 or approximately 4 billion, you don't need to worry about collisions. The higher the n, the more accurate this estimation. In fact the probability p(k) that a collision will occur with k keys approaches a step function as n gets larger, where the step occurs at k=Sqrt[n].


    Can you estimate the probability of a collision (i.e two keys that hash to the same value)? Let's say with 1,000 keys and with 10,000 keys?

    Assuming the hash function is uniformly distributed it's straightforward to derive the formula.

    p(no collision for k keys) = 1 * (n-1)/n * (n-2)/n * (n-3)/n * ... * (n-(k-1))/n
    

    That formula directly follows from starting with 1 key: The probability of no collision with 1 key is of course 1. The probability of no collision with 2 keys is 1 * (n-1)/n. And so on for all k keys. Conveniently, Mathematica has a Pochhammer[] function for this purpose to express this succinctly:

    p(no collision for k keys) = Pochhammer[n-(k-1),k]/n^k
    

    Then, to calculate the probability that there is at least 1 collision for k keys, subtract it from 1:

    p(k) = 1 - p(no collision for k keys) = 1 - Pochhammer[n-(k-1),k]/n^k
    

    Using Mathematica, one can calculate for n=2^64:

    • p(1,000) = 1 out of 3.7*1013
    • p(10,000) = 1 out of 3.7*1011
    • p(1,000,000) = 1 out of 3.7*107

    Is it safe to assume that a collision of a reasonable number of keys (say, less than 10,000 keys) is so improbable so that if 2 hash codes are the same we can say that the keys are the same without any further checking?

    To answer this precisely depends upon the probability that 2 of the 10,000 keys were identical. What we are looking for is:

    p(a=b|h(a)=h(b)) = The probability that a=b given h(a)=h(b)
    

    where a and b are keys (possibly identical) and h() is the hashing function. We can apply Bayes' Theorem directly:

    p(a=b|h(a)=h(b)) = p(h(a)=h(b)|a=b) * p(a=b) / p(h(a)=h(b))
    

    We immediately see that p(h(a)=h(b)|a=b) = 1 (if a=b then of course h(a)=h(b)) so we get

    p(a=b|h(a)=h(b)) = p(a=b) / p(h(a)=h(b))
    

    As you can see this depends upon p(a=b) which is the probability that a and b are actually the same key. This depends upon how the group of 10,000 keys were selected in the first place. The calculations for the previous two questions assume all keys are distinct, so more information on this scenario is needed to fully answer it.

    0 讨论(0)
  • 2021-02-04 07:57

    1) Is there a formula to estimate the probability of collisions taking into account the so-called Birthday Paradox?

    The probability of a single collision occurring depends on the key set generated as the hash function is uniform we can do following to calculate the probability that collision doesnt occurs at generation of k keys as follows :-

    x = hash size
    p(k=2) = (x-1)/x
    p(k=3) = p(k=2)*(x-2)/x
    ..
    p(k=n) = (x-1)*(x-2)..(x-n+1)/x^n
    
    p(k=n) ~ e^-(n*n)/2x
    
    p(collision|k=n) = 1-p(k=n) = 1 - e^(-n^2)/2x
    p(collision) > 0.5 if n ~ sqrt(x)
    

    Hence if sqrt(2^64) keys that is 2^32 key are generated there is higher chance that there is a single collision.

    2) Can you estimate the probability of a collision (i.e two keys that hash to the same value)? Let's say with 1,000 keys and with 10,000 keys?

    x = 2^64 
    Use the formula pc(k=n) = 1 - e^-(n^2)/2x
    

    3) Is it safe to assume that a collision of a reasonable number of keys (say, less than 10,000 keys) is so improbable so that if 2 hash codes are the same we can say that the keys are the same without any further checking?

    This is a very interesting question because it depends on the size of key space. Suppose your keys are generated at random from space of size = s and hash space is x=2^64 as you mentioned. Probability of collision is Pc(k=n|x) = 1-e^(-n^2)/2x. If Probability of choosing same key in key space is P(k=n|s) = 1-e^(-n^2)/2s . For it to be sure that if hash is same then keys are same:-

    P(k=n|s) > Pc(k=n|x)
    1-e^-(n^2/2s) > 1-e^-(n^2/2x) 
    n^2/2s > n^2/2x 
    s < x
    s < 2^64
    

    Hence it shows that for keys to be same if hash is same that key set size must be small than 2^64 approx otherwise there is a chance of collision in hash more than in key set. The result is independent of number of keys generated.

    0 讨论(0)
  • 2021-02-04 08:06

    Is there a formula to estimate the probability of collisions taking into account the so-called Birthday Paradox?

    See: Birthday attack.

    Assuming the distribution of hashes is uniform, the probability of a collision for n keys is approximately n2/265.

    Is it safe to assume that a collision of a reasonable number of keys (say, less than 10,000 keys) is so improbable so that if 2 hash codes are different we can say that the keys are different without any further checking?

    It's only safe when you use a cryptographic hash function. Even if you can tolerate a mistake every 3*1011 times, you may have to consider the possibility that the input is specifically built to create a hash collision, as an attack on your program.

    0 讨论(0)
  • 2021-02-04 08:11

    I'll provide a rough approximation to the exact formulas provided in the other answers; the approximation may be able to help you answer #3. The rough approximation is that the probability of a collision occurring with k keys and n possible hash values with a good hashing algorithm is approximately (k^2)/2n, for k << n. For 100,000 keys with a 64 bit hash, that's 10^10 / 32x10^18 or about 1 in 3 billion.

    However, I suspect that if you go with not checking the actual key values on collision, there is a larger chance you'll find out the hashing algorithm is not "good" enough, after all.

    0 讨论(0)
提交回复
热议问题