À quoi sert hashCode? Est-ce unique?

129

Je remarque qu'il existe une getHashCode()méthode dans tous les contrôles, éléments, dans WP7, qui renvoient une séquence de nombres. Puis-je utiliser ce hashcode pour identifier un élément? Par exemple, je souhaite identifier une image ou une chanson dans l'appareil et vérifier où elle se trouve. Cela pourrait être fait si le hashcode donné pour des éléments spécifiques est unique.

Pouvez-vous m'aider à m'expliquer à quoi sert hashCode et à quoi getHashCode()sert?

Nghia Nguyen
la source
Je sais ce que signifie hashCode, j'essaie d'exécuter mon code plusieurs fois pour obtenir le hashcode et il renvoie le même hashcode pour les mêmes éléments à chaque fois et ne semble pas être dupliqué, mais je ne suis tout simplement pas très sûr. Eh bien, ce n'est pas grave si vous voulez voter contre, c'est votre opinion. Merci pour la modification quand même!
Nghia Nguyen
7
Je recommande de lire les Directives et règles d' Eric Lippert pour GetHashCode , bien qu'il se concentre sur les règles d'implémentation des HashCodes plutôt que sur les règles pour les utiliser ... car ils sont " par conception utiles pour une seule chose: mettre un objet dans une table de hachage"
Brian

Réponses:

108

MSDN dit :

Un code de hachage est une valeur numérique utilisée pour identifier un objet lors des tests d'égalité. Il peut également servir d'index pour un objet dans une collection.

La méthode GetHashCode convient pour une utilisation dans des algorithmes de hachage et des structures de données telles qu'une table de hachage.

L'implémentation par défaut de la méthode GetHashCode ne garantit pas des valeurs de retour uniques pour différents objets. En outre, le .NET Framework ne garantit pas l'implémentation par défaut de la méthode GetHashCode et la valeur qu'il retourne sera la même entre les différentes versions du .NET Framework. Par conséquent, l'implémentation par défaut de cette méthode ne doit pas être utilisée comme identifiant d'objet unique à des fins de hachage.

La méthode GetHashCode peut être remplacée par un type dérivé. Les types valeur doivent remplacer cette méthode pour fournir une fonction de hachage appropriée pour ce type et pour fournir une distribution utile dans une table de hachage. Pour l'unicité, le code de hachage doit être basé sur la valeur d'un champ ou d'une propriété d'instance au lieu d'un champ ou d'une propriété statique.

Les objets utilisés comme clé dans un objet Hashtable doivent également remplacer la méthode GetHashCode car ces objets doivent générer leur propre code de hachage. Si un objet utilisé comme clé ne fournit pas une implémentation utile de GetHashCode, vous pouvez spécifier un fournisseur de code de hachage lorsque l'objet Hashtable est construit. Avant .NET Framework version 2.0, le fournisseur de code de hachage était basé sur l'interface System.Collections.IHashCodeProvider. À partir de la version 2.0, le fournisseur de code de hachage est basé sur l'interface System.Collections.IEqualityComparer.

Fondamentalement, les codes de hachage existent pour rendre les tables de hachage possibles.
Deux objets égaux sont garantis d'avoir des codes de hachage égaux.
Il n'est pas garanti que deux objets inégaux aient des codes de hachage inégaux (c'est ce qu'on appelle une collision).

SLaks
la source
3
La citation du MSDN est désormais obsolète. Le MSDN n'est plus aussi explicite que le code de hachage n'étant pas unique.
user34660
248

Après avoir appris de quoi il s'agissait, j'ai pensé écrire une explication plus simple, espérons-le, par analogie:

Résumé: Qu'est-ce qu'un hashcode?

  • C'est une empreinte digitale. Nous pouvons utiliser cette empreinte digitale pour identifier les personnes d'intérêt.

Lisez ci-dessous pour plus de détails:

Pensez à un Hashcode comme nous essayons d'identifier quelqu'un de manière unique

Je suis un détective, à la recherche d'un criminel. Appelons-le M. Cruel. (Il était un meurtrier notoire quand j'étais enfant - il est entré par effraction dans une maison kidnappée et assassiné une pauvre fille, a jeté son corps et il est toujours en liberté - mais c'est une autre affaire). M. Cruel a certaines caractéristiques particulières que je peux utiliser pour l'identifier de manière unique parmi une mer de gens. Nous avons 25 millions de personnes en Australie. L'un d'eux est M. Cruel. Comment le retrouver?

Mauvaises façons d'identifier M. Cruel

Apparemment, M. Cruel a les yeux bleus. Cela n'aide pas beaucoup, car près de la moitié de la population australienne a également les yeux bleus.

Bonnes façons d'identifier M. Cruel

Que puis-je utiliser d'autre? Je sais: j'utiliserai une empreinte digitale!

Avantages :

  • Il est vraiment très difficile pour deux personnes d'avoir la même empreinte digitale (pas impossible, mais extrêmement improbable).
  • L'empreinte digitale de M. Cruel ne changera jamais.
  • Chaque partie de l'être entier de M. Cruel: son apparence, sa couleur de cheveux, sa personnalité, ses habitudes alimentaires, etc. doivent (idéalement) se refléter dans son empreinte digitale, de sorte que s'il a un frère (qui est très similaire mais pas le même) - alors les deux devrait avoir des empreintes digitales différentes . Je dis "devrait" parce que nous ne pouvons pas garantir à 100% que deux personnes dans ce monde auront des empreintes digitales différentes.
  • Mais nous pouvons toujours garantir que M. Cruel aura toujours la même empreinte digitale - et que son empreinte digitale ne changera JAMAIS.

Les caractéristiques ci-dessus font généralement de bonnes fonctions de hachage.

Alors, quel est le problème avec les «collisions»?

Alors imaginez si je reçois une piste et que je trouve quelqu'un correspondant aux empreintes digitales de M. Cruel. Cela signifie-t-il que j'ai trouvé M. Cruel?

........ peut-être! Je dois regarder de plus près. Si j'utilise SHA256 (une fonction de hachage) et que je cherche dans une petite ville avec seulement 5 personnes - alors il y a de très bonnes chances que je le trouve! Mais si j'utilise MD5 (une autre fonction de hachage célèbre) et que je vérifie les empreintes digitales dans une ville de + 2 ^ 1000 personnes, alors c'est une assez bonne possibilité que deux personnes entièrement différentes aient la même empreinte digitale.

Alors quel est l'avantage de tout cela de toute façon?

Le seul véritable avantage des codes de hachage est que vous souhaitez mettre quelque chose dans une table de hachage - et avec les tables de hachage, vous voulez trouver des objets rapidement - et c'est là que le code de hachage entre en jeu. Ils vous permettent de trouver des éléments dans des tables de hachage vraiment rapidement. C'est un hack qui améliore considérablement les performances, mais à un petit prix de précision.

Alors imaginons que nous ayons une table de hachage remplie de personnes - 25 millions de suspects en Australie. M. Cruel est quelque part là-dedans ..... Comment pouvons-nous le trouver très rapidement ? Nous devons tous les trier: pour trouver une correspondance potentielle, ou pour acquitter autrement des suspects potentiels. Vous ne voulez pas tenir compte des caractéristiques uniques de chaque personne, car cela prendrait trop de temps. Que utiliseriez-vous à la place? Vous utiliseriez un hashcode! Un hashcode peut vous dire si deux personnes sont différentes. Si Joe Bloggs n'est PAS M. Cruel. Si les impressions ne correspondent pas, vous savez que ce n'est certainement PAS M. Cruel. Mais, si les empreintes digitales correspondentpuis selon la fonction de hachage que vous avez utilisée, il y a de fortes chances que vous ayez trouvé votre homme. Mais ce n'est pas à 100%. La seule façon dont vous pouvez être certain est d'enquêter plus avant: (i) a-t-il / elle eu une opportunité / un motif, (ii) des témoins, etc.

Lorsque vous utilisez des ordinateurs si deux objets ont la même valeur de code de hachage, vous devez à nouveau vérifier s'ils sont vraiment égaux. Par exemple, vous devriez vérifier si les objets ont par exemple la même hauteur, le même poids, etc., si les entiers sont les mêmes, ou si le customer_id est une correspondance, puis en venir à la conclusion s'ils sont identiques. cela se fait généralement peut-être en implémentant une interface IComparer ou IEquality.

Résumé clé

Donc, fondamentalement, un hashcode est une empreinte digitale.

Empreinte numérique - Attribut d'image à Pixabay - Librement disponible pour une utilisation sur: https://pixabay.com/en/finger-fingerprint-security-digital-2081169/

  1. Deux personnes / objets différents peuvent théoriquement toujours avoir la même empreinte digitale. Ou en d'autres termes. Si vous avez deux empreintes digitales identiques ... alors il n'est pas nécessaire qu'elles proviennent toutes les deux de la même personne / objet.
  2. Buuuuuut, la même personne / objet renverra toujours la même empreinte digitale .
  3. Ce qui signifie que si deux objets renvoient des codes de hachage différents, vous savez avec certitude à 100% que ces objets sont différents.

Cela prend 3 bonnes minutes pour comprendre ce qui précède. Peut-être lisez-le plusieurs fois jusqu'à ce qu'il ait du sens. J'espère que cela aide quelqu'un car il m'a fallu beaucoup de chagrin pour tout apprendre!

BKSpurgeon
la source
1
Re: La documentation MSDN a tué quelques-unes de mes cellules cérébrales ... en a conduit plusieurs au bord du suicide. sauvé seulement parce que je
me
Vous avez détruit toute votre belle explication avec ce commentaire astérisque à la fin.
Waldemar Gałęzinowski
Je l'ai aimé! principalement le nom "Mr.Cruel!
João Pedro Andrade Marques
En tant que véritable fan de crime, c'est probablement ma réponse SO la plus préférée ... jamais.
IfElseTryCatch le
11

GetHashCode()est utilisé pour aider à prendre en charge l'utilisation de l'objet comme clé pour les tables de hachage. (Une chose similaire existe en Java, etc.). Le but est que chaque objet renvoie un code de hachage distinct, mais cela ne peut souvent pas être absolument garanti. Il est cependant nécessaire que deux objets logiquement égaux retournent le même code de hachage.

Une implémentation typique de table de hachage commence par la valeur hashCode, prend un module (contraignant ainsi la valeur dans une plage) et l'utilise comme index d'un tableau de «buckets».

seand
la source
8

Ce n'est pas unique à WP7 - il est présent sur tous les objets .Net. Il fait en quelque sorte ce que vous décrivez, mais je ne le recommanderais pas comme identifiant unique dans vos applications, car il n'est pas garanti qu'il soit unique.

Object.GetHashCode, méthode

Phil Sandler
la source
4

Ceci est tiré de l'article msdn ici:

https://blogs.msdn.microsoft.com/tomarcher/2006/05/10/are-hash-codes-unique/

"Alors que vous entendrez des gens dire que les codes de hachage génèrent une valeur unique pour une entrée donnée, le fait est que, bien que difficile à réaliser, il est techniquement possible de trouver deux entrées de données différentes qui hachent à la même valeur . Cependant, le vrai les facteurs déterminants concernant l'efficacité d'un algorithme de hachage résident dans la longueur du code de hachage généré et la complexité des données hachées. "

Utilisez donc simplement un algorithme de hachage adapté à la taille de vos données et il aura des codes de hachage uniques.

Shree Harsha
la source