1

我开始用我的算法测试生成的 HashCodes 的唯一性哈希函数。我编写了下一个文本类来测试何时会生成相同的 hashCode。

class Program
{
    static void Main(string[] args)
    {
        var hashes = new List<int>();
        for (int i = 0; i < 100000; i++)
        {
            var vol = new Volume();
            var code = vol.GetHashCode();
            if (!hashes.Contains(code))
            {
                hashes.Add(code);
            }
            else
            {
                Console.WriteLine("Same hash code generated on the {0} retry", hashes.Count());
            }
        }
    }
}

public class Volume
{
    public Guid DriverId = Guid.NewGuid();
    public Guid ComputerId = Guid.NewGuid();
    public int Size;
    public ulong VersionNumber;
    public int HashCode;
    public static ulong CurDriverEpochNumber;
    public static Random RandomF = new Random();

    public Volume()
    {
        Size = RandomF.Next(1000000, 1200000);
        CurDriverEpochNumber ++;
        VersionNumber = CurDriverEpochNumber;
        HashCode = GetHashCodeInternal();
    }

    public int GetHashCodeInternal()
    {
        unchecked
        {
            var one = DriverId.GetHashCode() + ComputerId.GetHashCode() * 22;
            var two = (ulong)Size + VersionNumber;
            var result = one ^ (int)two;
            return result;
        }
    } 

}

GUID 字段 DriverId、ComputerId 和 int Size 是随机的。我假设在某个时候我们会生成相同的哈希码。你知道它会破坏大型收藏品的工作。神奇的是,生成重复哈希码时的重试次数是一样的!我多次运行示例代码并得到接近相同的结果:第一次在 10170 重试时重复运行,第二次在 7628 上运行,第三次在 7628 上运行,然后在 7628 上一次又一次地运行。有时我得到了一些其他结果。Bu 在大多数情况下是在 7628 上。

它对我没有任何解释。是不是中的错误。NET 随机生成器还是什么?


谢谢大家。现在很明显我的代码中存在错误(Matthew Watson)。我不得不调用 GetHashCodeIntelrnal() 而不是 GetHashCode()。最好的 GetHashCode 独特结果给了我:

    public int GetHashCodeInternal()
    {
        unchecked
        {
            var one = DriverId.GetHashCode() + ComputerId.GetHashCode();
            var two = ((ulong)Size) + VersionNumber;
            var result = one ^ (int)two << 32;
            return result;
        }
    } 

但是仍然在接近 140 000 它给出相同的代码......我认为这不好,因为我有接近 10 000 的收藏......

4

2 回答 2

2

如果您将 Console.WriteLine() 更改为也像这样打印 Volume.Size:

Console.WriteLine("Same hash code generated on the {0} retry ({1})", hashes.Count, vol.Size);

你会看到虽然hashes.Count第一次碰撞总是相同的,但vol.Size通常是不同的。

这似乎排除了导致此问题的随机数生成器 - 它看起来像GetHashCodeInternal().

仔细检查会发现您调用了错误的哈希码函数。

这一行:var code = vol.GetHashCode();

应该:var code = vol.HashCode;

试试吧!因为目前你正在调用默认的.Net GetHashCode(),它根本没有做你想做的事。

于 2013-04-05T10:54:46.477 回答
1

您将需要传入随机数生成器,创建一个要重用的随机数生成器,因为目前您正在创建它们的新实例太靠近,这导致使用相同的种子,因此出现相同的数字序列出去。

您的结果将 在从种子日期的下一个滴答声/秒生成种子的点上看似随机地随机出现。所以,只是偶然,真的。

于 2013-04-05T10:36:14.390 回答