生日悖论

一个与概率有关的问题:在一群人里,至少两个人生日相同(月和日)的概率有多大?如果想要碰到生日相同的人的概率超过 50%,这一群人至少要多少人?很多人认为至少要 365/2=183 个人,但是实际上只需要 23 人就够了,大家认为的 183 人和实际只需要 23 人就是这个悖论的意思。

这个概率是如何计算的?

我们没有办法去直接计算“至少有一对相同”的概率,因为这里面涉及的不只是两个人的生日可能相同的事件,也可能涉及三个人的生日相同的事件,这些事件互相重叠,会使计算的难度增加。所以我们要使用概率论里的“容斥原理”来尝试解决这个问题。不要去直接计算生日相同的事件概率,而是去计算所有的人的生日都不会相同的这个事件的概率,然后再使用 1 减去这个概率就可以得到至少有一对两个人的生日是相同的事件的概率。

1 个人的生日不存在与其它人相同这个事件,所以 1 个人与他人生日相同这个事件的概率为 0 。

2 个人出现生日相同的事件的概率。首先,365 代表着一年有 365 天,所以有 365 种可能性。第一个人在 365 天都不会有生日相同的问题,他与其它人的生日相同的事件概率为 1 。而第二个人,与第一个人的生日在 365 天中有 364 天是不同的,所以第二个人与第一个人的生日不同的概率为 364/365 。所以,两个人生日各自不同的最终概率就是这两个概率值相乘,再使用 1 减去这个最终的概率,就得到两个人任意一个人的生日与其它人的生日相同的概率了。使用乘法,是因为这两个事件的概率需要同时发生。

使用容斥原理来计算,就是如下公式:

P=1365365364365=13643650.00274P=1-\frac{365}{365}*\frac{364}{365}=1-\frac{364}{365}\approx0.00274

23 个人出现生日相同的事件的概率。由 2 人出现生日相同的事件的概率可推导出以下的公式:

P=1365365364365363365...343365=1P(365,23)36523=0.5073P = 1-\frac{365}{365}*\frac{364}{365}*\frac{363}{365}*…*\frac{343}{365}=1-\frac{P(365,23)}{365^{23}}=0.5073

其中 P(365,23) 指的是:从 365 个不同元素中,选出 23 个,并且“顺序不同算不同情况”的总数,也就是 365*364*363*…*(365-22)。

生日悖论的问题本质上是在研究在有限的空间 M 中,不同数量 N 的样本出现相同的情况的概率。在生日悖论中,有限的空间就是 M,而 23 个人就是样本数量 N。

哈希碰撞问题

众所周知,Hash256 总共 32 个字节。如果我存储完整的哈希值到文件中,当哈希数量多时,这将是一个巨大的存储空间开销。所以,想办法缩减这个哈希值的存储空间,就能够省掉很多不必要的空间。那么到底要缩短到什么样的长度,同时也能让出现重复的概率变得低到可以让人接受呢?这就是生日悖论所讨论的问题。

碰撞公式

当你的数据比较大时,你不可能使用上方的阶乘公式来计算,于是这里有一个简化版本的碰撞公式,可以用它来进行简单的碰撞计算(M 为碰撞空间,而 N 为样本数量):

PN22MP\approx\frac{N^2}{2M}

但是它得到的结果是一个近似值,对于非常小的样本,得出的结果偏差非常大。例如,套入生日悖论中的 23 人的碰撞概率,计算得出来的结果是:

23223650.725\frac{23^2}{2*365}\approx0.725

但是我们用它来计算大数是完全没有问题的,得出来的结果与实际结果相差不大。

比特币地址存储压缩

举个例子:比特币的接收地址,各种类型揉到一起打包可以获得一个 32 字节的哈希值,我想对该值进行裁剪,那么应该裁剪到多少个字节,使得其占用空间变小同时保持低碰撞概率?

我们假设整个比特币网络中会存在有 1000 亿个地址,如果我们给出的空间是 11 字节,那么碰撞的概率是多少呢?

P(1011)22(28)11102222880.000016P\approx\frac{(10^{11})^2}{2*(2^8)^{11}}\approx\frac{10^22}{2*2^{88}}\approx0.000016

所以,如果存储 11 个字节做为裁剪后的哈希,那么当全网有 1000 亿个地址时,有可能出现重复的概率为 0.000016 ,这个概率其实有点到临界位置。但是因为全网现在远远没有达到那么多地址数量,在可预见的未来也很难达到,所以相对来说,取 11 个字节是一个比较合适的长度。

This article was written by matthew

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注