给定哈希长度的广义生日计算

时间:2012-06-10 08:56:53

标签: hash birthday-paradox

让我们假设我们得到以下内容:

  • 哈希的长度
  • 获得碰撞的机会

现在,了解上述情况,我们如何获得获得给定机会百分比所需的“样本”数量?

2 个答案:

答案 0 :(得分:0)

当我们将Simplified formula作为生日悖论时,我们得到:

probability = k^2/2N

所以:

sqr(probability*2*n) = k

我们知道n = 2 ^ lenghtHash

小测试: 散列= 16位:N = 65536 概率= 50%= 0.5

sqr(0.5 * 2 * 65536)= 256 samples

这不是100%正确,因为我们开始使用简化公式,但对于大哈希和较大的样本集,它非常接近。

有关公式的链接,您可以查看here

答案 1 :(得分:0)

这是一个小小的javascript函数,用于基于https://preshing.com/20110504/hash-collision-probabilities/(感谢链接@Frank)的“简化近似”算法来计算碰撞几率,并使用{{3} }管理比Javascript Number所能处理的数字更大的数字,例如:

samples=2**64; //
hash_size_bytes=20; // 160 bit hash
number_of_possible_hashes=Decimal("2").pow(8*hash_size_bytes);
console.log(collision_chance(samples,number_of_possible_hashes));
// ~ 0.00000001 % chance of a collision with 2**64 samples and 20-byte-long hashes.
samples=77163;
hash_size_bytes=4; // 32bit hash
number_of_possible_hashes=Decimal("2").pow(8*hash_size_bytes);
console.log(collision_chance(samples,number_of_possible_hashes));
// ~ 49.999% chance of a collision for a 4-byte hash with 77163 samples.

功能:

// with https://github.com/MikeMcl/decimal.js/blob/master/decimal.min.js
function collision_chance(samples,number_of_possible_hashes){
    var Decimal100 = Decimal.clone({ precision: 100, rounding: 8 });
    var k=Decimal100(samples);
    var N=Decimal100(number_of_possible_hashes);
    var MinusK=Decimal100(samples);
    MinusK.s=-1;
    var ret=((MinusK.mul(k.sub(1))).div(N.mul(2))).exp();
    ret=ret.mul(100);
    ret=Decimal100(100).sub(ret);
    return ret.toFixed(100);
}