C# Создайте хэш для байтового массива или изображения
Вопрос
Возможный дубликат:
Как мне создать хэш-код из массива байтов в С#
В C# мне нужно создать хэш изображения, чтобы гарантировать его уникальность в хранилище.
Я могу легко преобразовать его в массив байтов, но не знаю, как действовать дальше.
Есть ли какие-либо классы в .NET Framework, которые могут мне помочь, или кто-нибудь знает о некоторых эффективный алгоритмы для создания такого уникального хеша?
Решение
В .NET существует множество поставщиков хеш-сумм, которые создают криптографические хеши, что удовлетворяет вашему условию их уникальности (для большинства целей защищенных от коллизий).Они все очень сильно быстро, и хеширование определенно не станет узким местом в вашем приложении, если вы не будете делать это триллион раз.
Лично мне нравится SHA1:
string hash;
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
}
Даже когда люди говорят, что один метод может быть медленнее другого, это все относительно.Программа, работающая с изображениями, точно не заметит микросекундный процесс генерации хэш-суммы.
А что касается столкновений, то для большинства целей это тоже неактуально.Даже «устаревшие» методы, такие как MD5, по-прежнему весьма полезны в большинстве ситуаций.Только рекомендуем не использовать его, когда безопасность вашей системы полагается по предотвращению столкновений.
Другие советы
Часть Ответ Рекса М. об использовании SHA1 для генерации хеша — хороший вариант (MD5 также является популярным вариантом).Предложение Зволкова о том, чтобы не создавать постоянно новых поставщиков криптовалют, также является хорошим (как и предложение об использовании CRC, если скорость важнее, чем практически гарантированная уникальность).
Тем не менее, сделайте нет использовать Кодировка.UTF8.GetString() для преобразования byte[] в строку (если, конечно, из контекста вы не знаете, что это допустимая UTF8).Во-первых, это будет отклонить недействительные суррогаты.Метод, который гарантированно всегда даст вам действительную строку из byte[]: Конвертировать.ToBase64String().
Создание нового экземпляра SHA1CryptoServiceProvider каждый раз, когда вам нужно вычислить хэш, совсем НЕ быстро.Использование одного и того же экземпляра происходит довольно быстро.
Тем не менее, я бы предпочел использовать один из многих алгоритмов CRC вместо криптографического хеша, поскольку хеш-функции, разработанные для криптографии, не слишком хорошо работают для очень маленьких размеров хэша (32 бита), а это то, что вам нужно для переопределения GetHash() ( при условии, что вы этого хотите).
Посмотрите эту ссылку, чтобы увидеть один из примеров вычисления CRC на C#: http://sanity-free.org/134/standard_crc_16_in_csharp.html
P.S.Причина, по которой вы хотите, чтобы ваш хэш был небольшим (16 или 32 бита), заключается в том, чтобы вы могли БЫСТРО сравнивать их (в этом и был весь смысл наличия хэшей, помните?).Иметь хэш, представленный 256-битным значением, закодированным в виде строки, довольно безумно с точки зрения производительности.
Вы можете использовать любой стандартный алгоритм хеширования, но хеширование технически не может гарантировать уникальность.Хеширование спроектировано как относительно быстрый и/или небольшой токен, позволяющий определить, совпадает ли один фрагмент данных с другим.Вполне возможно, что совершенно разные наборы данных будут создавать один и тот же хеш, хотя алгоритмически создать их очень сложно.
Помимо всего этого, для проверки вероятной личности MD5 работает довольно быстро.SHA более надежен (MD5 был взломан, поэтому его не следует использовать в целях безопасности), но он также медленнее.