如何在c#中使用Object.GetHashCode()比较两个巨大的byte []数组?

时间:2012-10-09 08:47:19

标签: c# arrays

我不太明白为什么Object.GetHashCode()为两个相同的字节数组返回不同的值,但为非IEnumerable值类型对象返回相等的值。例如:

byte e = 123;
Console.WriteLine(e.GetHashCode());

byte f = 123;
Console.WriteLine(f.GetHashCode());

输出

123
123

byte[] a = new byte[3] { 1, 2, 3 };
Console.WriteLine(a.GetHashCode());

byte[] b = new byte[3] { 1, 2, 3 };
Console.WriteLine(b.GetHashCode());

输出

46104728
12289376

为什么会如此,如何在不比较每个元素的情况下快速比较两个巨大的数组?

3 个答案:

答案 0 :(得分:4)

GetHashCode没有为数组类型定义 - 你必须实现自己的哈希算法。

您看到的值实际上是基于底层引用,因此两个相同的数组将始终具有不同的哈希代码,除非它们是相同的引用。

对于32位或更少的整数类型,哈希码等于转换为32位整数的值。对于64位整数类型Int64,高32位与散列码的低32位(也存在移位)进行异或。

因此,当试图快速比较两个阵列时,你必须自己做。

您可以先使用逻辑检查 - 长度相等,以相同的字节值开始和结束等。然后您可以选择 - 逐字节读取和比较值(或者您可以读取4或8个字节)一段时间并使用BitConverter将字节块转换为Int32Int64以生成可能更快检查相等的一对值或使用通用哈希函数来很好地猜测相等。

为此,您可以使用MD5哈希 - 使用MD5输出哈希非常快:How do I generate a hashcode from a byte array in C#?

从这样的哈希函数中获取两个相同的哈希值并不保证相等,但一般来说,如果要比较同一数据“空间”中的字节数组,则不应该发生冲突。我的意思是,通常,相同类型的不同数据的示例应该几乎总是产生不同的哈希值。网上有很多比我有资格解释的更多。

答案 1 :(得分:1)

Try by use SHA1CryptoServiceProvider.ComputeHash method? 
It takes a byte array and returns a SHA1 hash which is identical 
for byte arrays. Performance is good.

string byte1hash; string byte2hash;
using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { byte1hash= Convert.ToBase64String(sha1.ComputeHash(byteArray1)); byte2hash= Convert.ToBase64String(sha1.ComputeHash(byteArray2));
} if (string.Equals(byte1hash, byte2hash)) { //States the byte arrays are same.. }

If you are not worried about security, then you go for MD5

答案 2 :(得分:0)

默认情况下,对于引用类型,GetHashCode从引用计算哈希码,而不是从对象的内容计算哈希码。

我认为你运气不好,要计算数组的哈希码,你需要至少检查一次数组的内容