A cosa serve hashCode? È unico?


129

Ho notato che esiste un getHashCode()metodo in ogni controllo, elemento, in WP7, che restituisce una sequenza numerica. Posso usare questo hashcode per identificare un oggetto? Ad esempio, desidero identificare un'immagine o un brano nel dispositivo e verificarlo dove si trova. Questo potrebbe essere fatto se l'hashcode fornito per elementi specifici è unico.

Potete aiutarmi a spiegarmi a cosa serve hashCode e a cosa getHashCode()serve?


So cosa significa hashCode, provo a eseguire il mio codice molte volte per ottenere l'hashcode e restituire lo stesso hashcode per gli stessi elementi ogni volta e non sembra essere duplicato, ma non ne sono molto sicuro. Bene, va bene se vuoi sottovalutare, è la tua opinione. Grazie comunque per la modifica!
Nghia Nguyen,

7
Consiglio di leggere le Linee guida e le regole di Eric Lippert per GetHashCode , sebbene si concentri sulle regole per l'implementazione degli HashCodes piuttosto che sulle regole per usarli ... in quanto sono " progettualmente utili per una sola cosa: mettere un oggetto in una tabella hash"
Brian

Risposte:


108

MSDN dice :

Un codice hash è un valore numerico utilizzato per identificare un oggetto durante il test di uguaglianza. Può anche servire come indice per un oggetto in una raccolta.

Il metodo GetHashCode è adatto per l'uso in algoritmi di hashing e strutture dati come una tabella hash.

L'implementazione predefinita del metodo GetHashCode non garantisce valori di ritorno univoci per oggetti diversi. Inoltre, .NET Framework non garantisce l'implementazione predefinita del metodo GetHashCode e il valore che restituisce sarà lo stesso tra le diverse versioni di .NET Framework. Di conseguenza, l'implementazione predefinita di questo metodo non deve essere utilizzata come identificatore univoco di oggetti per scopi di hashing.

Il metodo GetHashCode può essere sovrascritto da un tipo derivato. I tipi di valore devono sovrascrivere questo metodo per fornire una funzione hash appropriata per quel tipo e per fornire una distribuzione utile in una tabella hash. Per unicità, il codice hash deve essere basato sul valore di un campo o di una proprietà dell'istanza anziché su un campo o una proprietà statici.

Gli oggetti utilizzati come chiave in un oggetto Hashtable devono anche sostituire il metodo GetHashCode perché tali oggetti devono generare il proprio codice hash. Se un oggetto utilizzato come chiave non fornisce un'implementazione utile di GetHashCode, è possibile specificare un provider di codice hash quando viene costruito l'oggetto Hashtable. Prima di .NET Framework versione 2.0, il provider del codice hash era basato sull'interfaccia System.Collections.IHashCodeProvider. A partire dalla versione 2.0, il provider del codice hash si basa sull'interfaccia System.Collections.IEqualityComparer.

Fondamentalmente, esistono codici hash per rendere possibili hashtable.
È garantito che due oggetti uguali abbiano hashcode uguali. Non è garantito che
due oggetti disuguali abbiano hashcode disuguali (che si chiama collisione).


3
La citazione da MSDN non è più aggiornata. MSDN ora non è così esplicito sul fatto che il codice hash non sia univoco.
user34660,

248

Dopo aver appreso di cosa si tratta, ho pensato di scrivere una spiegazione, si spera, più semplice tramite l'analogia:

Riepilogo: che cos'è un hashcode?

  • È un'impronta digitale. Possiamo usare questa impronta digitale per identificare le persone di interesse.

Leggere sotto per ulteriori dettagli:

Pensa a un Hashcode mentre cerchiamo di identificare in modo univoco qualcuno

Sono un detective, alla ricerca di un criminale. Chiamiamolo signor Cruel. (Era un famigerato assassino quando ero un bambino - ha fatto irruzione in una casa rapita e ucciso una povera ragazza, ha scaricato il suo corpo ed è ancora in libertà - ma è una questione separata). L'onorevole Cruel ha alcune caratteristiche peculiari che posso usare per identificarlo in modo univoco in un mare di persone. Abbiamo 25 milioni di persone in Australia. Uno di questi è il signor Cruel. Come possiamo trovarlo?

Cattivi modi di identificare Mr Cruel

Apparentemente il signor Cruel ha gli occhi blu. Questo non è di grande aiuto perché quasi la metà della popolazione in Australia ha anche gli occhi blu.

Buoni modi per identificare Mr Cruel

Cos'altro posso usare? Lo so: userò un'impronta digitale!

Vantaggi :

  • È davvero difficile per due persone avere la stessa impronta digitale (non impossibile, ma estremamente improbabile).
  • L'impronta digitale di Mr Cruel non cambierà mai.
  • Ogni singola parte dell'intero essere di Mr Cruel: il suo aspetto, il colore dei capelli, la personalità, le abitudini alimentari ecc. Devono (idealmente) riflettersi nella sua impronta digitale, in modo tale che se ha un fratello (che è molto simile ma non uguale) - allora entrambi dovrebbe avere impronte digitali diverse . Dico "dovrei" perché non possiamo garantire al 100% che due persone in questo mondo avranno impronte digitali diverse.
  • Ma possiamo sempre garantire che Mr Cruel avrà sempre la stessa impronta digitale e che la sua impronta digitale non cambierà MAI.

Le caratteristiche di cui sopra generalmente offrono buone funzioni di hash.

Allora, qual è il problema con 'Collisioni'?

Quindi immagina se ottengo un vantaggio e trovo qualcuno che corrisponda alle impronte digitali di Mr Cruel. Questo significa che ho trovato Mr Cruel?

........Forse! Devo dare un'occhiata più da vicino. Se sto usando SHA256 (una funzione di hashing) e sto cercando in una piccola città con solo 5 persone - allora ho ottime possibilità di trovarlo! Ma se sto usando MD5 (un'altra famosa funzione di hashing) e sto cercando le impronte digitali in una città con + 2 ^ 1000 persone, allora è una buona possibilità che due persone completamente diverse possano avere la stessa impronta digitale.

Qual è comunque il vantaggio di tutto ciò?

L'unico vero vantaggio degli hashcodes è se vuoi mettere qualcosa in una tabella hash - e con le tabelle hash vorresti trovare oggetti rapidamente - ed è qui che entra in gioco il codice hash. Ti permettono di trovare cose nelle tabelle hash velocemente. È un hack che migliora notevolmente le prestazioni, ma con una piccola spesa di precisione.

Quindi immaginiamo di avere un tavolo di hash pieno di gente - 25 milioni di sospetti in Australia. Mr Cruel è da qualche parte lì dentro ... Come possiamo trovarlo molto velocemente ? Dobbiamo selezionarli tutti: per trovare una potenziale corrispondenza o per assolvere potenziali sospetti. Non vuoi considerare le caratteristiche uniche di ogni persona perché ciò richiederebbe troppo tempo. Cosa useresti invece? Useresti un hashcode! Un hashcode può dirti se due persone sono diverse. Se Joe Bloggs NON è Mr Cruel. Se le stampe non corrispondono, allora sai che NON è assolutamente Mr Cruel. Ma, se le impronte digitali corrispondonoquindi a seconda della funzione hash che hai usato, è probabile che tu abbia già trovato il tuo uomo abbastanza buono. Ma non è al 100%. L'unico modo per essere certi è indagare ulteriormente: (i) ha avuto un'opportunità / motivo, (ii) testimoni ecc. Ecc.

Quando si utilizzano computer se due oggetti hanno lo stesso valore del codice hash, è necessario verificare nuovamente se sono veramente uguali. ad es. Dovresti verificare se gli oggetti hanno ad es. la stessa altezza, lo stesso peso ecc., se gli interi sono uguali o se il cliente_id è una corrispondenza, e poi giungi alla conclusione se sono uguali. questo è in genere fatto forse implementando interfacce IComparer o IEquality.

Riepilogo chiave

Quindi in pratica un hashcode è un'impronta digitale.

Impronta digitale - Attributo dell'immagine a Pixabay - Disponibile gratuitamente su: https://pixabay.com/it/finger-fingerprint-security-digital-2081169/

  1. Due persone / oggetti diversi possono teoricamente avere ancora la stessa impronta digitale. O in altre parole. Se hai due impronte digitali uguali ......... non devono necessariamente provenire entrambi dalla stessa persona / oggetto.
  2. Buuuuuut, la stessa persona / oggetto restituirà sempre la stessa impronta digitale .
  3. Ciò significa che se due oggetti restituiscono codici hash diversi , allora sai con certezza al 100% che quegli oggetti sono diversi.

Ci vogliono ben 3 minuti per capovolgere quanto sopra. Forse leggilo un paio di volte finché non ha senso. Spero che questo aiuti qualcuno perché ci è voluto molto dolore per imparare tutto!


1
Ri: La documentazione di MSDN ha ucciso alcune delle mie cellule cerebrali ... ha portato un bel po 'delle mie al limite del suicidio. salvato solo perché mi sono addormentato;)
Shwrk

Alla fine hai distrutto tutta la tua bella spiegazione con quell'asterisco.
Waldemar Gałęzinowski,

Lo amavo! principalmente il nome "Mr.Cruel!
João Pedro Andrade Marques,

Come un vero fan del crimine, questa è probabilmente la mia risposta SO più preferita ... di sempre.
IfElse TryCatch

11

GetHashCode()viene utilizzato per aiutare a supportare l'utilizzo dell'oggetto come chiave per le tabelle hash. (Una cosa simile esiste in Java ecc.). L'obiettivo è che ogni oggetto restituisca un codice hash distinto, ma questo spesso non può essere assolutamente garantito. È necessario tuttavia che due oggetti logicamente uguali restituiscano lo stesso codice hash.

Una tipica implementazione della tabella hash inizia con il valore hashCode, accetta un modulo (vincolando così il valore all'interno di un intervallo) e lo utilizza come indice in una matrice di "bucket".


8

Non è univoco per WP7, è presente su tutti gli oggetti .Net. Fa un po 'quello che descrivi, ma non lo consiglierei come identificatore univoco nelle tue app, in quanto non è garantito che sia univoco.

Metodo Object.GetHashCode


4

Questo è dall'articolo msdn qui:

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

"Mentre sentirai che le persone dichiarano che i codici hash generano un valore univoco per un determinato input, il fatto è che, sebbene difficile da realizzare, è tecnicamente possibile trovare due diversi input di dati che abbiano lo stesso valore . Tuttavia, il vero fattori determinanti per quanto riguarda l'efficacia di un algoritmo hash risiedono nella lunghezza del codice hash generato e nella complessità dei dati sottoposti a hash. "

Quindi basta usare un algoritmo di hash adatto alle dimensioni dei dati e avrà hashcode univoci.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.