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

StackOverflow https://stackoverflow.com/questions/800463

  •  03-07-2019
  •  | 
  •  

Вопрос

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

В 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 был взломан, поэтому его не следует использовать в целях безопасности), но он также медленнее.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top