Подтвердить что ты не робот

С# Создать хэш для байтового массива или изображения

Возможный дубликат:
Как создать хэш-код из массива байтов в С#

В С# мне нужно создать хэш изображения, чтобы убедиться, что он уникален в памяти.

Я могу легко преобразовать его в массив байтов, но не знаю, как исходить оттуда.

Существуют ли какие-либо классы в платформе .NET, которые могут мне помочь, или кто-нибудь знает о некоторых эффективных алгоритмах для создания такого уникального хэша?

4b9b3361

Ответ 1

В .NET существует множество поставщиков hashsum, которые создают криптографические хэши, что удовлетворяет вашему условию, что они уникальны (для большинства целей - для предотвращения конфликтов). Все они очень быстрые, и хеширование определенно не будет узким местом в вашем приложении, если вы не делаете это в триллион раз.

Лично мне нравится SHA1:

string hash;
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
    hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
}

Даже когда люди говорят, что один метод может быть медленнее другого, все это в относительном выражении. Программа, обращаясь к изображениям, определенно не увидит микросекундный процесс генерации хешсума.

И что касается коллизий, для большинства целей это тоже не имеет значения. Даже "устаревшие" методы, такие как MD5, по-прежнему очень полезны в большинстве ситуаций. Рекомендовать не рекомендуется, когда безопасность вашей системы зависит от предотвращения столкновений.

Ответ 2

Часть Rex M answer об использовании SHA1 для генерации хэша является хорошей (MD5 также является популярным вариантом). Предложение zvolkov о том, что не постоянно создаются новые криптопровайдеры, также является хорошим (как и предположение об использовании CRC, если скорость важнее, чем виртуально гарантированная уникальность.

Однако не используйте Encoding.UTF8.GetString() для преобразования байта [] в строку (если, конечно, вы не знаете из контекста, что это действительно UTF8). Во-первых, отклонить недействительные суррогаты. Метод, гарантированный всегда, дает вам действительную строку из байта []: Convert.ToBase64String().

Ответ 3

Создание нового экземпляра SHA1CryptoServiceProvider каждый раз, когда вам нужно вычислить хэш, НЕ является быстрым. Использование того же экземпляра довольно быстро.

Тем не менее, я бы предпочел сделать один из многих алгоритмов CRC вместо криптографического хэша, поскольку хеш-функции, предназначенные для криптографии, не слишком хорошо работают для очень маленьких размеров хэша (32 бит), что и нужно для вашего GetHash ( ) переопределить (предполагая, что вы хотите).

Проверьте эту ссылку на один пример вычисления CRC в С#: http://sanity-free.org/134/standard_crc_16_in_csharp.html

P.S. причина, по которой вы хотите, чтобы ваш хеш был небольшим (16 или 32 бит), так вы можете сравнить их FAST (это была цель хэши, помните?). Наличие хеша, представленного 256-битным длинным значением, закодированным как строка, является довольно сумасшедшим с точки зрения производительности.

Ответ 4

Вы можете использовать любой из стандартных алгоритмов хеширования, но хеширование не может технически гарантировать уникальность. Хеширование предназначено для того, чтобы быть относительно быстрым и/или небольшим токеном, чтобы иметь возможность увидеть, является ли одна часть данных такой же, как и другая. Вполне возможно, что для совершенно разных наборов данных для получения одного и того же хэша, хотя возможность их генерировать алгоритмически очень сложно.

Все это в стороне, для проверки вероятной личности MD5 довольно быстро. SHA более надежен (MD5 взломан, поэтому его нельзя использовать для обеспечения безопасности), но он также медленнее.