我開始使用我的算法測試生成的HashCodes的唯一性的哈希函數。我寫了下一個文本類來測試何時會生成相同的hashCode。加入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大小是隨機的。 我認爲在某個時候我們會生成相同的散列碼。你知道它會打破大集合的工作。魔術實際上是當重複的 哈希碼生成時的重試數是相同的!我運行了幾次示例代碼並得到了接近相同的結果:冷杉在10170重試上運行重複,在7628上運行第二個,在7628上運行第三個7628 ,並且一次又一次在7628上運行。有時候我得到了一些其他結果。在大多數情況下它是在7628.
它對我沒有任何解釋。 它是錯誤的。 NET隨機發生器還是什麼?
謝謝大家。現在很明顯,我的代碼中存在bug(馬修沃森)。我不得不調用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集...
*你知道它會打破大集合的工作。* - 你爲什麼這麼想? – MarcinJuraszek 2013-04-05 10:30:28
隨機數發生器只是一個僞隨機數發生器(http://en.wikipedia.org/wiki/Pseudorandom_number_generator),這意味着結果可以以某種方式預測。 – pascalhein 2013-04-05 10:31:36
「你爲什麼這麼想?」 - 如果在集合中有什麼項目具有相同的哈希碼?或者如果某些地方有通過hashCode進行搜索但存在其他對象的hashCode呢?這是正常的嗎? – 2013-04-05 10:37:24