md5cryptoserviceprovider - hmacsha256 c#
¿Métodos de código hash adecuados para una matriz de bytes? (4)
¿Cuál es el mejor método hash para una matriz de byte
?
Las matrices son objetos de clase serializados que contienen imágenes jpeg pasadas entre aplicaciones a través de TCP / IP.
El tamaño de la matriz es de aproximadamente 200k.
Basado en el Compilador Generado 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;
}
}
Ah ... y un enlace a C # Murmurhash http://landman-code.blogspot.com/2009/02/c-superfasthash-and-murmurhash2.html
Cualquiera de las cosas de cifrado hash debería funcionar. No estoy seguro de la velocidad. Tal vez MD5?
Cualquiera de las funciones hash incorporadas debería hacer; dependiendo de cuánto te importen las colisiones, estas son tus opciones (desde la mayoría de las colisiones al menos):
- MD5
- SHA1
- SHA256
- SHA384
- SHA512
Son tan simples de usar como:
var hash = SHA1.Create().ComputeHash(data);
Marcas de bonificación: si no te importa la seguridad (lo que no creo que hagas dado que obtienes los valores hash de las imágenes), tal vez quieras investigar el hash Murmur, que está diseñado para hash de contenido y no hashing seguro ( y por lo tanto es mucho más rápido). Sin embargo, no está en el marco, por lo que tendrá que encontrar una implementación (y probablemente debería optar por Murmur3).
Editar: Si está buscando un HASHCODE para una matriz de bytes [], depende totalmente de usted, por lo general consiste en cambiar de bit (por primos) y XORing. P.ej
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);
EDITAR: Si quiere validar que el valor no ha cambiado, debe usar CRC32 .
Jon Skeet tiene una buena respuesta sobre cómo anular GetHashCode
, que se basa en técnicas de hash efectivas generales en las que comienzas con un número primo, lo agregas a los códigos hash de los componentes multiplicados por otro número primo, permitiendo el desbordamiento.
Para su caso, usted haría:
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;
}
}
Nota en la respuesta de Jon explica por qué esto es mejor que XORing los hash de los elementos individuales (y que los tipos anónimos en C # actualmente no usan XOR en los hash de los elementos individuales, sino que usan algo similar al anterior).
Si bien esto será más rápido que los algoritmos hash del espacio de nombres System.Security.Cryptography
(porque se trata de hashes más pequeños), la desventaja es que es posible que tenga más colisiones.
Tendría que probar en contra de sus datos y determinar con qué frecuencia se producen colisiones en comparación con el trabajo que se debe realizar en caso de colisión.