什么是适用于byte
数组的最佳哈希方法?
这些数组是包含jpeg图像的序列化类对象,在TCP/IP应用程序之间传递。
数组大小约为200k。
什么是适用于byte
数组的最佳哈希方法?
这些数组是包含jpeg图像的序列化类对象,在TCP/IP应用程序之间传递。
数组大小约为200k。
任何内置的哈希函数都可以使用;根据您对冲突的在意程度,以下是您的选择(从最多冲突到最少):
它们的使用方法很简单,如下所示:
var hash = SHA1.Create().ComputeHash(data);
额外加分:如果你不关心安全(考虑到你正在获取图像的哈希值,我认为你并不关心),你可能想考虑Murmur哈希,它是用于内容哈希而不是安全哈希的(因此速度更快)。然而,它不在框架中,因此您需要找到实现(并且您应该选择Murmur3)。
编辑:如果您正在寻找byte[]数组的HASHCODE,那完全取决于您自己,它通常由位移(通过质数)和XORing组成。例如:
public class ByteArrayEqualityComparer : IEqualityComparer<byte[]>
{
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);
编辑: 如果您想要验证值是否已更改,则应使用CRC32。
Jon Skeet有一个很好的答案,讲述如何重写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;
}
}
System.Security.Cryptography
命名空间中的哈希算法快(因为你处理的哈希值较小),但缺点是可能会有更多的冲突。foreach
比 for
慢吗?此外,在 byte
上不需要调用 GetHashCode
,因为它只返回其转换为 int
的值。 - Drew Noakesforeach
改为 for
。但这只是一个实现细节,通常情况下,你应该测试一下是否存在瓶颈。同样,对于字节的 GetHashCode
返回值也是如此。 - casperOnepublic 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
任何加密哈希相关的内容都应该可用。关于速度并不确定,也许使用MD5?
byte[]
数组的32位值。序列化对象随其哈希一起发送到其他计算机,在那里重新计算哈希值并进行比较。 - Chesnokov Yuriy
byte[]
数组内容,不需要加密哈希。我需要确保发送的数据在接收端保持不变。 - Chesnokov Yuriy