Go 戈朗';s MD5分布似乎不均匀?

Go 戈朗';s MD5分布似乎不均匀?,go,hash,md5,Go,Hash,Md5,我完全希望我在某个地方有一个bug,或者我误解了什么,但是为什么下面的代码看起来没有呈现统一的分布呢 func TestMD5(t *testing.T) { n := 50000 counts := map[uint32]int{} // # of hashes per 1/nth shard for i := 0; i < n; i++ { hash := md5.Sum(newUUID()) result := binary.

我完全希望我在某个地方有一个bug,或者我误解了什么,但是为什么下面的代码看起来没有呈现统一的分布呢

func TestMD5(t *testing.T) {
    n := 50000
    counts := map[uint32]int{} // # of hashes per 1/nth shard

    for i := 0; i < n; i++ {
        hash := md5.Sum(newUUID())
        result := binary.BigEndian.Uint32(hash[:4])
        counts[result/uint32(n)]++
    }

    dupeShards := 0
    dupeEntries := 0
    for _, count := range counts {
        if count > 1 {
            dupeShards++
            dupeEntries += count - 1
        }
    }
    t.Logf("%d inputs hashed to the same %d shards as other inputs.", dupeEntries, dupeShards)

    if len(counts) < n*95/100 {
        t.Fatalf("%d populated shards not within 5%% of expected %d uniform distribution!", len(counts), n)
    }
}

我也可以用其他散列(例如FNV)来重新编程,所以我猜我误解了什么。谢谢你的帮助

这是绝对正常的行为,并且没有显示MD5实现的任何偏差或错误

你所做的是(非常接近)从0到49999之间随机抽取50000个数字。当你这样做时,几乎可以肯定的是,许多数字会重复,因此一些数字不会出现。事实上,50000个数字不太可能完全不同,绝对不重复

你可以用一个六面骰子来测试这一点——如果你掷六次骰子,你不太可能得到全部六个数字,更可能看到其中的三个、四个或五个,重复一次、两次或三次。这也与所谓的

这种现象的另一个例子是“帕尼尼贴纸问题”。帕尼尼贴纸相册是一本可以放置600张足球贴纸的书,纪念世界杯足球赛。每一个都是有编号的、不同的,它们在数据包中是随机的。你必须在每个号码中选一个才能完成相册。假设您购买了正确数量的贴纸来填充相册。如果你能够完美地填满这张专辑,而没有任何翻倍或丢失的贴纸,那将是非常幸运的。事实上,如果你不与其他收藏家交换复制品,你必须平均购买大量的贴纸,才能得到至少一张

出现的不同值0-49999的数量和显示“聚集”的数量可以通过数学计算得出。我不确定你到底是如何测量聚集的。但从一次试验到下一次试验,38K填充值的值将非常稳定,即使您看到的实际值将发生变化


事实上,填充值的预期数量是(1-1/e)n,其中n是可能值的数量,e是数学常数2.718281828。。。n=50000的答案是31606。当然,您不会总是得到这个值,但所有结果都应该在几百个左右(这里是spitballing)。你在程序中犯了一个小错误,所以我无法破译相关的计算结果,得出37000左右

这是绝对正常的行为,并且没有显示MD5实现的任何偏差或错误

你所做的是(非常接近)从0到49999之间随机抽取50000个数字。当你这样做时,几乎可以肯定的是,许多数字会重复,因此一些数字不会出现。事实上,50000个数字不太可能完全不同,绝对不重复

你可以用一个六面骰子来测试这一点——如果你掷六次骰子,你不太可能得到全部六个数字,更可能看到其中的三个、四个或五个,重复一次、两次或三次。这也与所谓的

这种现象的另一个例子是“帕尼尼贴纸问题”。帕尼尼贴纸相册是一本可以放置600张足球贴纸的书,纪念世界杯足球赛。每一个都是有编号的、不同的,它们在数据包中是随机的。你必须在每个号码中选一个才能完成相册。假设您购买了正确数量的贴纸来填充相册。如果你能够完美地填满这张专辑,而没有任何翻倍或丢失的贴纸,那将是非常幸运的。事实上,如果你不与其他收藏家交换复制品,你必须平均购买大量的贴纸,才能得到至少一张

出现的不同值0-49999的数量和显示“聚集”的数量可以通过数学计算得出。我不确定你到底是如何测量聚集的。但从一次试验到下一次试验,38K填充值的值将非常稳定,即使您看到的实际值将发生变化


事实上,填充值的预期数量是(1-1/e)n,其中n是可能值的数量,e是数学常数2.718281828。。。n=50000的答案是31606。当然,您不会总是得到这个值,但所有结果都应该在几百个左右(这里是spitballing)。你在程序中犯了一个小错误,所以我无法破译相关的计算结果,得出37000左右

这很正常。这就是从一个统一的发行版中进行绘图应该是什么样子的。您是否将其与其他MD5实现进行了比较?好吧,这是一个定义好的算法,实现可能会有所不同,但结果却不一样!所以,你的问题的“开始”部分已经是一条红鲱鱼了。而且,你把输出放入1+(2^32)/50000桶,而不是50000桶。如果你把它们扔进50000个桶中,你会看到更多的输出落在同一个桶中。@user2357112:你能解释一下桶的注释吗?我将所有可能的
1+(2^32)
值的空间除以50000,这就是50k个桶,不是吗?考虑到下面的答案,这似乎也是正确的,因为这些桶中只有38k个被填满。啊,我现在意识到了!我需要
%
,而不是
/
。这很正常。这就是从一个统一的发行版中进行绘图应该是什么样子的。您是否将其与其他MD5实现进行了比较?好吧,这是一个定义好的算法,实现可能会有所不同,但结果却不一样!所以,你的问题的“开始”部分已经是一条红鲱鱼了。而且,你把输出放入1+(2^32)/50000桶,而不是50000桶。如果你把它们扔进50000个桶中,你会看到更多的输出落在同一个桶中。@user2357112:你能解释一下桶的注释吗?我正在除法(用截断法)
main.go:29: 12075 inputs hashed to the same 9921 shards as other inputs.
main.go:32: 37925 populated shards not within 5% of expected 50000 uniform distribution!