2012-10-09 29 views
0

我不太明白为什么Object.GetHashCode()为两个相同的字节数组返回不同的值,但为不是IEnumerable值类型对象返回相同的值。例如:如何使用C#中的Object.GetHashCode()比较两个巨大的byte []数组?

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 

为什么会这样,我怎么能快速比较两个巨大数组没有比较他们的每个元素?

+1

的hashCode平等**!= **平等 – spender

回答

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#?

从这样一个散列函数获取两个相同的散列值不会保证保证相等,但是一般情况下,如果您要在同一数据'空间'内比较字节数组,您不应该发生冲突。我的意思是说,总的来说,相同类型的不同数据的例子几乎总是会产生不同的散列。网络上有很多比我有资格解释的更多。

0

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

我觉得你的运气了,来计算阵列的哈希码,你需要去通过阵列的内容的,至少一次

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