适合字节数组的哈希码方法?

对于一个byte数组,最好的哈希方法是什么?

这些数组是序列化的类对象,包含通过TCP / IP在应用程序之间传递的jpeg图像。

arrays大小约为200k。

任何内置的散列函数都应该这样做; 根据您对碰撞的关注程度,这些是您的选择(从大多数碰撞到最少碰撞):

  • MD5
  • SHA1
  • SHA256
  • SHA3​​84
  • SHA512

它们的使用简单如下:

 var hash = SHA1.Create().ComputeHash(data); 

奖励标记:如果您不关心安全性(我认为您没有给出图像的哈希值),您可能需要查看Murmur哈希,它是专为内容哈希而非安全哈希设计的(并因此更快)。 但是,它不是在框架中,所以你必须找到一个实现(你应该去找Murmur3)。

编辑:如果你正在寻找一个byte []数组的HASHCODE ,它完全取决于你,它通常包括位移(通过素数)和异或。 例如

 public class ByteArrayEqualityComparer : IEqualityComparer { public static readonly ByteArrayEqualityComparer Default = new ByteArrayEqualityComparer(); private ByteArrayEqualityComparer() { } public bool Equals(byte[] x, byte[] y) { if (x == null && y == null) return true; if (x == null || y == null) return false; if (x.Length != y.Length) return false; for (var i = 0; i < x.Length; i++) if (x[i] != y[i]) return false; return true; } public int GetHashCode(byte[] obj) { if (obj == null || obj.Length == 0) return 0; var hashCode = 0; for (var i = 0; i < obj.Length; i++) // Rotate by 3 bits and XOR the new value. hashCode = (hashCode << 3) | (hashCode >> (29)) ^ obj[i]; return hashCode; } } // ... var hc = ByteArrayEqualityComparer.Default.GetHashCode(data); 

编辑:如果要validation值未更改,则应使用CRC32 。

Jon Skeet对如何覆盖GetHashCode 有一个很好的答案 , GetHashCode基于一般有效的哈希技术,你从素数开始,将它添加到组件的哈希码乘以另一个素数,允许溢出。

对于您的情况,您会这样做:

 static int GetByteArrayHashCode(byte[] array) { unchecked { int hash = 17; // Cycle through each element in the array. foreach (var value in array) { // Update the hash. hash = hash * 23 + value.GetHashCode(); } return hash; } } 

注意在Jon的回答中,他解释了为什么这比对各个元素的哈希进行异或更好(并且C#中的匿名类型当前不会对各个元素的哈希进行异或,而是使用类似于上面的内容)。

虽然这将比System.Security.Cryptography命名空间中的哈希算法更快(因为您正在处理较小的哈希值),但缺点是您可能会有更多冲突。

您必须针对您的数据进行测试,并确定您在发生碰撞时与碰撞时需要完成的工作的频率。

任何加密哈希的东西都应该有效。 不确定速度。 MD5也许?

基于编译器生成的GetHashCode()

 public static int GetHashCode(byte[] array) { unchecked { int i = 0; int hash = 17; int rounded = array.Length & ~3; hash = 31 * hash + array.Length; for (; i < rounded; i += 4) { hash = 31 * hash + BitConverter.ToInt32(array, i); } if (i < array.Length) { int val = array[i]; i++; if (i < array.Length) { val |= array[i] << 8; i++; if (i < array.Length) { val |= array[i] << 16; } } hash = 31 * hash + val; } return hash; } } 

啊......以及C#Murmurhash的链接http://landman-code.blogspot.com/2009/02/c-superfasthash-and-murmurhash2.html