Подходящие методы хэш-кода для массива байтов?
каков наилучший метод хэша для массива byte
?
массивы-это сериализованные объекты класса, содержащие изображение jpeg, передаваемое между приложениями по TCP / IP.
размер массива составляет около 200k.
4 ответов
любая из встроенных функций хэширования должна делать; в зависимости от того, насколько вы заботитесь о столкновениях, это ваши варианты (от большинства столкновений до наименьшего):
- MD5 в
- в SHA1
- SHA256 и
- значения sha384
- криптография SHA512
Они так же просты в использовании как:
var hash = SHA1.Create().ComputeHash(data);
Бонусные Знаки: если вы не заботитесь о безопасности (что я не думаю, что вы делаете, учитывая, что вы получаете хэши для изображений) вы можете посмотреть в хеше Murmur, который предназначен для хэширования контента, а не для безопасного хэширования (и, таким образом, намного быстрее). Однако это не в рамках, поэтому вам придется найти реализацию (и вы, вероятно, должны пойти на Murmur3).
Edit: если вы ищете хэш-код для массива byte[] это полностью зависит от вас, он обычно состоит из битового сдвига (по простым числам) и 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 в.
у Джона Скита есть хороший ответ о том, как переопределить 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;
}
}
Примечание В ответе Джона он объясняет, почему это лучше, чем XORing хэшей отдельных элементов (и что анонимные типы В C# в настоящее время не XOR хэши отдельных элементов, но использовать что-то подобное выше).
В то время как это будет быстрее, чем хэш-алгоритмы из System.Security.Cryptography
пространство имен (потому что вы имеете дело с меньшими хэшами), недостатком является то, что у вас может быть больше столкновений.
вам придется протестировать свои данные и определить, как часто вы получаете столкновения против работы, которая должна быть выполнена в случае столкновения.
на основе Компилятор Сгенерировал 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