均匀分配给定属性的哈希

时间:2019-02-14 16:51:37

标签: c# algorithm hash md5 distribution

我正在尝试在多个存储桶中分配一组项目。我正在寻找以下属性:

  1. 桶分配必须确定。在不同的运行中相同 输入应最终位于同一存储桶中。

  2. 存储分区之间的数据分配应该是均匀的。

  3. 这应该适用于相当少量的输入(例如,如果我想 在25个存储分区中分配50个输入,理想情况下,每个存储分区将 有2个项目。)

首先尝试从输入数据生成md5,并从md5的第一个字节形成存储桶。我对统一性不太满意。当输入较大时,它可以很好地工作,但对于较小的输入,则不能很好地工作。例如。在64个存储桶中分配100个项目:

List<string> l = new List<string>();

for (int i = 0; i < 100; i++)
{
    l.Add(string.Format("data{0}.txt", i));
}

int[] buckets = new int[64];

var md5 = MD5.Create();
foreach (string str in l)
{
    {
        byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(str));
        uint bucket = BitConverter.ToUInt32(hash, 0) % 64;
        buckets[bucket % 64]++;
    }
}

Histogram

任何建议我该怎么做才能获得更高的均匀性?谢谢。

1 个答案:

答案 0 :(得分:1)

不考虑将MD5用于此目的的效率(请参见讨论here和该问题的带标记的重复内容),基本上答案是您所拥有的就是均匀分布的真正外观。 / p>

这似乎是违反直觉的,但是很容易通过数学或实验证明。

作为一种激励示例,请考虑在0-63范围内准确选择64个数字的任务。每个存储桶中获得一个的几率非常接近0。共有64 64 个可能的序列,其中64个!包含所有64个数字。获得这些序列之一的几率约为3.1×10 26 之一。实际上,获得一个没有元素出现三遍的序列的几率小于千分之一(约.000658)。因此,几乎可以肯定的是,在0-63范围内的64个数字的随机统一样本将具有一些三胞胎,并且很可能会有一些四胞胎。如果样本是100个数字,那么这些概率将变得更大。

但是一般而言,数学并不是那么容易计算,因此我在这里选择使用random.org通过实验进行演示:-),这是一个非常可靠的随机数源。我要求它提供0-63范围内的100个数字,并对其进行计数(使用bash,因此我的“图形”不如您的漂亮)。这是两次运行:

首次运行:

Random numbers: 
44  17  50  11  16   4  24  29  12  36
27  32  12  63   4  30  19  60  28  39
22  40  19  16  23   2  46  31  52  41
13   2  42  17  29  39  43   9  20  50
45  40  38  33  17  45  28   6  48  12
56  26  34  33  35  40  28  44  22  10
50  55  49  43  63  62  22  50  15  52
48  54  53  26   4  53  13  56  42  60
49  30  14  55  29  62  15  13  35  40
22  38  37  36  10  36   5  41  43  53

Counts:                                                                
                      X                 X         X             
    X       XX   X    X     XX      X   X  X      X  X          
  X X     X XX XXX X  X   X XXX  X XX XXXXXXXX  XXX XX XX   X XX
  X XXX  XXXXXXXXX XX XXX XXXXXXXXXXXXXXXXXXXXX XXX XXXXX   X XX
----------------------------------------------------------------
          1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6
0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2

第二次运行:

Random numbers:
41  31  16  40   1  51  17  41  27  46
24  14  21  33  25  43   4  36   1  14
40  22  11  22  30  19  23  63  39  61
 8  55  40   6  21  13  55  13   3  52
17  52  53  53   7  21  47  13  45  57
25  27  30  48  38  55  55  22  61  11
11  28  45  63  43   0  41  51  15   2
33   2  46  14  35  41   5   2  11  37
28  56  15   7  18  12  57  36  59  51
42   5  46  32  10   8   0  46  12   9

Counts:
           X                             X    X        X        
  X        X XX      XX                 XX    X    X   X        
XXX  X XX  XXXXX X   XX  X XX X  X  X   XX X XX    XXX X X   X X
XXXXXXXXXXXXXXXXXXXX XXXXX XX XXXX XXXXXXXXX XXXX  XXX XXX X X X
----------------------------------------------------------------
          1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6
0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2

您可以使用自己喜欢的随机数生成器尝试此操作,并根据分布的大小进行调整。您将获得相同的形状。