适合字节数组的哈希码方法
本文关键字:哈希码 方法 数组 字节数 字节 | 更新日期: 2023-09-27 18:06:57
byte
数组的最佳哈希方法是什么?
数组是序列化的类对象,包含通过TCP/IP在应用程序之间传递的jpeg图像。
数组大小约为200k
任何内置的哈希函数都可以;根据你对碰撞的关心程度,这些是你的选择(从大多数碰撞到最少):
- MD5
- SHA1
- SHA256
- SHA384
- SHA512
使用起来很简单:
var hash = SHA1.Create().ComputeHash(data);
奖励标记:如果你不关心安全性(我认为你不关心,因为你正在获取图像的哈希),你可能想看看杂音哈希,它是为内容哈希而不是安全哈希而设计的(因此要快得多)。但是,它不在框架中,因此您必须找到实现(并且您可能应该选择Murmur3)。
Edit:如果您正在为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);
EDIT:如果你想验证值没有改变,你应该使用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;
}
}
注意在Jon的回答中,他解释了为什么这比XORing单个元素的哈希值更好(并且c#中的匿名类型目前不XOR单个元素的哈希值,而是使用类似于上面的东西)。
虽然这将比来自System.Security.Cryptography
名称空间的哈希算法更快(因为您正在处理较小的哈希),但缺点是您可能会有更多的冲突。
你必须对你的数据进行测试,并确定发生碰撞的频率,以及在发生碰撞的情况下需要做的工作。
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
任何加密散列的东西应该工作。速度不太确定。也许MD5 ?