web-dev-qa-db-fra.com

C # Créer un hachage pour un tableau d'octets ou une image

Duplicata possible:
Comment générer un code de hachage à partir d'un tableau d'octets en c #

En C #, je dois créer un hachage d'une image pour m'assurer qu'elle est unique en stockage.

Je peux facilement le convertir en un tableau d'octets, mais je ne sais pas comment procéder à partir de là.

Y a-t-il des classes dans le framework .NET qui peuvent m'aider, ou quelqu'un connaît-il des algorithmes efficaces pour créer un hachage aussi unique?

38
johnc

Il existe de nombreux fournisseurs de hashs dans .NET qui créent des hachages cryptographiques - ce qui satisfait votre condition selon laquelle ils sont uniques (dans la plupart des cas, anti-collision). Ils sont tous extrêmement rapides et le hachage ne sera certainement pas le goulot d'étranglement dans votre application, sauf si vous le faites un billion de fois.

Personnellement, j'aime SHA1:

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

Même lorsque les gens disent qu'une méthode peut être plus lente qu'une autre, tout est relatif. Un programme traitant d'images ne remarquera certainement pas le processus en microsecondes de génération d'un hachage.

Et en ce qui concerne les collisions, dans la plupart des cas, cela n'est pas non plus pertinent. Même les méthodes "obsolètes" comme MD5 sont toujours très utiles dans la plupart des situations. Ne recommande de ne pas l'utiliser lorsque la sécurité de votre système repose sur la prévention des collisions.

60
Rex M

La partie de réponse de Rex M sur l'utilisation de SHA1 pour générer un hachage est bonne (MD5 est également une option populaire). La suggestion de zvolkov de ne pas créer constamment de nouveaux fournisseurs de crypto est également bonne (tout comme la suggestion d'utiliser CRC si la vitesse est plus importante que l'unicité virtuellement garantie.

Cependant, n'utilisez pas Encoding.UTF8.GetString () pour convertir un octet [] en chaîne (sauf bien sûr vous savez du contexte qu'il est valide UTF8). D'une part, il rejetera les substituts invalides . Une méthode garantie de toujours vous donner une chaîne valide à partir d'un octet [] est Convert.ToBase64String () .

15
Jonathan Rupp

La création d'une nouvelle instance de SHA1CryptoServiceProvider à chaque fois que vous avez besoin de calculer un hachage n'est PAS du tout rapide. Utiliser la même instance est assez rapide.

Je préfère toujours utiliser l'un des nombreux algorithmes CRC au lieu d'un hachage cryptographique, car les fonctions de hachage conçues pour la cryptographie ne fonctionnent pas trop bien pour les très petites tailles de hachage (32 bits), ce qui est ce que vous voulez pour votre remplacement GetHash () ( en supposant que c'est ce que vous voulez).

Consultez ce lien pour un exemple de calcul CRC en C #: http://sanity-free.org/134/standard_crc_16_in_csharp.html

P.S. la raison pour laquelle vous voulez que votre hachage soit petit (16 ou 32 bits) est que vous puissiez les comparer RAPIDEMENT (c'était tout l'intérêt d'avoir des hachages, vous vous souvenez?). Avoir un hachage représenté par une valeur longue de 256 bits encodée en chaîne est assez insensé en termes de performances.

5
zvolkov

Vous pouvez utiliser n'importe lequel des algorithmes de hachage standard, mais le hachage ne peut pas garantir techniquement l'unicité. Le hachage est conçu pour être un jeton relativement rapide et/ou petit pour pouvoir voir si un élément de données est probablement le même que l'autre. Il est tout à fait possible que des ensembles de données entièrement différents produisent le même hachage, bien qu'il soit très difficile de produire ces algorithmes.

Tout cela mis à part, pour vérifier l'identité probable, MD5 est assez rapide. SHA est plus fiable (MD5 a été piraté, ne devrait donc pas être utilisé pour la sécurité), mais il est également plus lent.

4
Adam Robinson