0

我不太明白为什么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

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

4

3 回答 3

4

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

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

对于 32 位或更少的整数类型,哈希码等于转换为 32 位整数的值。对于 64 位整数类型,Int64高 32 位与低 32 位进行异或运算(那里也有移位)作为哈希码。

因此,在尝试“快速”比较两个数组时,您必须自己动手。

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

为此,您可以使用 MD5 哈希 - 使用 MD5 输出哈希非常快:如何在 C# 中从字节数组生成哈希码?.

从这样的散列函数中获取两个相同的散列值并不能保证相等,但一般来说,如果您在同一数据“空间”内比较字节数组,则不应发生冲突。我的意思是,一般来说,相同类型的不同数据的示例几乎总是会产生不同的哈希值。网上关于这方面的内容比我有资格解释的要多得多。

于 2012-10-09T08:50:34.527 回答
1

尝试使用 SHA1CryptoServiceProvider.ComputeHash 方法?
它需要一个字节数组并返回一个相同的 SHA1 哈希
对于字节数组。性能很好。

字符串字节1哈希; 字符串字节2哈希;
使用 (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { byte1hash=Convert.ToBase64String(sha1.ComputeHash(byteArray1)); byte2hash=Convert.ToBase64String(sha1.ComputeHash(byteArray2));
} if (string.Equals(byte1hash, byte2hash)) { //状态字节数组是相同的.. }

如果您不担心安全性,那么您可以选择 MD5

于 2012-12-18T11:10:03.473 回答
0

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

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

于 2012-10-09T08:49:54.793 回答