Che cosa è esattamente (e precisamente) "hash?"


38

Ho sentito la parola "hash" usata in contesti diversi (tutti nel mondo dell'informatica) con significati diversi. Ad esempio, nel libro Learn Python the Hard Way, nel capitolo sui dizionari si dice "Python li chiama" dicts. "Altre lingue li chiamano" hash "." "Allora, sono dizionari hash?

L'altro uso comune della parola è in relazione alla crittografia. Ho anche sentito (e letto) persone usare la parola "hash" come una funzione specifica all'interno della programmazione di alto livello.

Quindi, che cos'è esattamente?

Qualcuno (con il tempo e chi è ben informato) può gentilmente spiegare le nozioni di "hash (o hash)?"


8
Wikipedia ha articoli dettagliati su tabelle hash e funzioni hash crittografiche . Cosa stai cercando che non è in quelli?
David Richerby,

1
Hai già elencato più usi del termine "hash" e ce ne sono altri. Quindi, come ti aspetti esattamente di ottenere una risposta a "che cos'è esattamente?"
Raffaello

4
"Hash" in questo senso è una riduzione delle "tabelle hash", ad esempio tabelle che usano hash per l'organizzazione delle chiavi. È un po 'come chiamare benzina "gas" - non ti aspetti che il "gas" sia gassoso o che i gas abbiano proprietà simili alla benzina, vero? Questo succede sempre con il linguaggio - l'accorciamento in particolare sono fonti molto comuni di sovrapposizione di parole.
Luaan,

1
"Non esiste una definizione per questa parola: nessuno sa cos'è l'hash." - The Devil's Dictionary
jpmc26,

Per quanto riguarda i diversi treni di pensiero che cos'è una funzione hash: una funzione hash è solo una funzione con un mucchio di proprietà, ma non è il modo in cui è definito che è rilevante, è quali proprietà vogliamo che abbia - che deriviamo da come vogliamo per usare la funzione - è rilevante. Poiché vogliamo usarlo per accedere rapidamente alle cose, vogliamo che sia calcolabile in modo efficiente. Poiché non abbiamo uno spazio infinito disponibile, vogliamo che il codice sia finito. Poiché vogliamo evitare le collisioni nel miglior modo possibile, vogliamo che la funzione hash distribuisca gli hash in modo uniforme.
G. Bach,

Risposte:


44

L'articolo di Wikipedia sulle funzioni di hash è molto buono, ma qui darò la mia opinione.


Che cos'è un hash?

"Hash" è in realtà un termine generico con significati formali diversi in contesti diversi. Non esiste un'unica risposta perfetta alla tua domanda. Spiegherò il concetto generale alla base e menzionerò alcuni degli usi più comuni del termine.

Un "hash" è una funzione definita funzione hash che accetta come oggetti di input e genera una stringa o un numero. Gli oggetti di input sono generalmente membri di tipi di dati di base come stringhe, numeri interi o più grandi composti da altri oggetti come strutture definite dall'utente. L'output è in genere un numero o una stringa. Il nome "hash" si riferisce spesso a questo output. Il verbo "hash" spesso significa "applica una funzione hash". Le proprietà principali che dovrebbe avere una funzione hash sono:h

  1. Dovrebbe essere facile da calcolare e
  2. Gli output dovrebbero essere relativamente piccoli.

Esempio:

Supponiamo di voler eseguire l'hashing dei numeri nell'intervallo da 0 a 999.999.999 al numero compreso tra 0 e 99. Una semplice funzione di hash può essere .h(X)=Xmod100

Proprietà aggiuntive comuni:

A seconda del caso d'uso, è possibile che la funzione hash soddisfi le proprietà aggiuntive. Ecco alcune proprietà aggiuntive comuni:

  1. Uniformità : spesso vogliamo che gli hash degli oggetti siano distinti. Inoltre potremmo voler "diffondere" gli hash. Se voglio eseguire l'hashing di alcuni oggetti in 100 bucket (quindi l'output della mia funzione hash è un numero compreso tra 0 e 99), di solito spero che circa 1/100 oggetti atterrino nel bucket 0, circa 1/100 atterrino in secchio 1 e così via.

  2. Resistenza alle collisioni crittografiche : a volte questo è preso ancora di più, ad esempio, nella crittografia potrei volere una funzione hash tale che per un avversario è difficile dal punto di vista computazionale trovare due input diversi che mappano sullo stesso output.

  3. Compressione : spesso desidero eseguire il hash di input arbitrariamente grandi in un output di dimensioni costanti o in un numero fisso di bucket.

  4. Determinismo : potrei desiderare una funzione hash il cui output non cambi tra le esecuzioni, ovvero l'output della funzione hash sullo stesso oggetto rimarrà sempre lo stesso. Ciò può sembrare in conflitto con l'uniformità di cui sopra, ma una soluzione è scegliere una volta la funzione hash in modo casuale e non cambiarla tra le esecuzioni.


Alcune applicazioni

Un'applicazione comune è in strutture di dati come una tabella hash, che sono un modo per implementare dizionari. Qui, allocare un po 'di memoria, diciamo, 100 "secchi"; quindi, quando viene richiesto di memorizzare una coppia (chiave, valore) nel dizionario, si esegue l'hashing della chiave in un numero 0-99 e si memorizza la coppia nel bucket corrispondente in memoria. Quindi, quando ti viene chiesto di cercare una chiave, esegui l'hashing della chiave in un numero 0-99 con la stessa funzione hash e controlla quel bucket per vedere se quella chiave è lì. In tal caso, si restituisce il suo valore.

Tieni presente che puoi anche implementare dizionari in altri modi, ad esempio con un albero di ricerca binario (se i tuoi oggetti sono comparabili).

Un'altra applicazione pratica sono i checksum, che sono modi per verificare che due file siano uguali (ad esempio, il file non è stato danneggiato dalla sua versione precedente). Poiché è molto improbabile che le funzioni hash mappino due input allo stesso output, si calcola e memorizza un hash del primo file, solitamente rappresentato come una stringa. Questo hash è molto piccolo, forse solo poche decine di caratteri ASCII. Quindi, quando si ottiene il secondo file, l'hash e si verifica che l'output sia lo stesso. In tal caso, quasi sicuramente è lo stesso file byte per byte.

Un'altra applicazione è nella crittografia, in cui questi hash dovrebbero essere difficili da "invertire" - vale a dire, dato l'output e la funzione hash, dovrebbe essere difficile dal punto di vista computazionale l'input che ha portato a quell'output. Un uso di questo è per le password: invece di archiviare la password stessa, memorizzi un hash crittografico della password (forse con alcuni altri ingredienti). Quindi, quando un utente immette una password, calcoli il suo hash e controlli che corrisponda all'hash corretto; in tal caso, dici che la password è corretta. (Ora anche qualcuno che può cercare e scoprire l'hash salvato sul server non ha un tempo così semplice fingendo di essere l'utente.) Questa applicazione può essere un caso in cui l'output è lungo o più lungo dell'input, dal momento che l'ingresso è così breve.


1
Bella spiegazione ma non sono d'accordo con "molto improbabile". Vedi: programmers.stackexchange.com/questions/49550/… : si verificano collisioni e talvolta sorprendentemente spesso.
Olivier Dulac il

8
Si noti inoltre che nel contesto della crittografia, il termine "hash" implica fortemente un'operazione "unidirezionale" che non può essere facilmente annullata nella pratica. Quando può essere facilmente invertito, si chiama "crittografia". Questo è il motivo per cui le persone su Security.SE ti diranno di eseguire sempre l'hashing delle password dei tuoi clienti, senza mai crittografarle.
Ixrec,

4
Un hash che non si "allarga" è ancora un hash, forse non molto valido per la tua applicazione.
Smetti di fare del male a Monica il

1
Certo, questi sono tutti punti positivi.
usul

10

Una funzione hash è una funzione che accetta un input e produce un valore di dimensione fissa. Ad esempio, potresti avere una funzione hash stringHashche accetta una stringdi qualsiasi lunghezza e produce un numero intero a 32 bit.

In genere è corretto affermare che l'output di una funzione hash è un hash (noto anche come valore hash o somma hash). Tuttavia, a volte le persone si riferiscono alla funzione stessa come a un hash . Questo è tecnicamente scorretto, ma di solito viene trascurato in quanto è generalmente inteso (nel contesto) che la persona intendesse funzione hash .

L'uso tipico di una funzione hash è di implementare una tabella hash . Una tabella hash è una struttura di dati che associa valori ad altri valori generalmente indicati come chiavi. Lo fa usando una funzione hash sulla chiave per produrre un valore hash di dimensioni fisse che può usare per una rapida ricerca dei dati che memorizza. Non entrerò nei dettagli completi su come lo fa, ma il fatto chiave qui è che viene chiamato una tabella hash perché si basa su una funzione hash per produrre valori hash (hash).

È qui che entra in gioco una parte della confusione, perché alcune persone (di nuovo, in qualche modo erroneamente) si riferiscono a una tabella di hash come hash. Come indicato in altre risposte, a volte l'implementazione di una determinata tabella di una tabella di hash si riferisce alla tabella di hash come hash (in particolare Perl fa questo, anche se mi aspetto che lo facciano anche altre lingue). Altre lingue scelgono di fare riferimento alla loro implementazione di una tabella hash come dizionario. Python è uno di questi linguaggi, ma a causa del modo in cui sono radicati nella lingua, molti utenti di Python accorciano il termine dizionario a "dict".

Quindi, mentre l'uso corretto del termine hash è riferirsi al valore di hash prodotto da una funzione hash , le persone a volte usano il termine in modo informale per riferirsi a funzioni hash e tabelle hash , creando così la confusione.


2
Non sono sicuro che sia veramente errato fare riferimento a una tabella hash o alla funzione hash come "hash" (non sembra peggio che, ad esempio, usare "Washington" per indicare "gli Stati Uniti", come in " Washington ha accolto con favore la dichiarazione della Cina "). Ma sono d'accordo che è confuso ed è positivo che tu sia molto chiaro su questo nella tua risposta.
David Richerby,

1
@DavidRicherby Formalmente, direi che il lavoro "hash" non è definito. "Funzione hash", "valore hash", "tabella hash" e "hash una stringa" hanno tutti definizioni matematiche precise ma "hash" è ambiguo. Allo stesso modo, so cosa intendi con "Washington", ma la tua frase ha ancora senso se interpreto "Washington" nel senso di "George Washington" o "Denzel Washington" piuttosto che "La città di Washington", che è un modo altamente informale riferirsi al governo federale. In conclusione: fare attenzione a non confondere "sapere cosa intendi" per una definizione formale rigorosa.
Mike Ounsworth,

@DavidRicherby Non è un'analogia equivalente. L'erroneità è discutibile ma l'informalità no.
Pharap,

2

Una funzione hash è sostanzialmente qualsiasi funzione in cui l'immagine è più piccola del dominio . L'output di tale funzione f(x)può essere definito "l'hash di x".

Nell'informatica incontriamo tipicamente due applicazioni delle funzioni hash.

Il primo è per le strutture di dati come le tabelle hash , in cui vogliamo mappare il dominio chiave (es. Numeri interi a 32 bit o stringhe di lunghezza arbitraria) su un indice di array (es. Numero intero compreso tra 0 e 100). L'obiettivo qui è massimizzare le prestazioni della struttura dei dati; le proprietà della funzione hash che sono in genere desiderabili sono la semplicità e la distribuzione uniforme dell'output.

Perl chiama il suo array associativo incorporato un "hash" , che sembra essere ciò che sta causando la tua confusione qui. Non conosco altre lingue che lo fanno. Liberamente la struttura dei dati potrebbe essere vista come una funzione hash stessa (dove il dominio è il set corrente di chiavi), ma è anche implementata come una tabella hash.

Il secondo è per la crittografia : autenticazione dei messaggi, verifica della password / firma, ecc. Il dominio è in genere stringhe di byte arbitrarie. Qui ci occupiamo di sicurezza - che a volte significa prestazioni deliberatamente basse - dove proprietà utili sono la collisione e la resistenza pre-immagine.


E ho ancora obiezioni alla tua prima frase perché quando si esegue l'hashing di password di 32 caratteri con SHA-512, lo spazio di input è in realtà più piccolo dello spazio di output. Quando si concatenano funzioni hash insieme, il dominio e l'intervallo sono gli stessi; la dimensione dello spazio di input è irrilevante. La risposta di Pharap ha la definizione corretta: "Una funzione hash è qualsiasi funzione con output a lunghezza fissa". Questo è tutto, è tutto ciò di cui hai bisogno, tutte le altre condizioni di cui stai parlando sono implicite da ciò.
Mike Ounsworth,

@MikeOunsworth ma il dominio di SHA-512 è stringhe binarie di lunghezza arbitraria. Suppongo di poter rubare la formulazione dei Pharaps, ma stavo cercando di rendere esplicite le condizioni a beneficio del PO. In realtà non sono sicuro che "di lunghezza fissa" sia necessario, né definito in modo inequivocabile.
Smetti di fare del male a Monica il

@OrangeDog Ok, ma posso avvolgere SHA-512 all'interno di una funzione chiamata MikesHash()che accetta stringhe di lunghezza 12 e le passa a SHA-512 e restituisce l'output. Sono abbastanza sicuro che MikesHash()soddisfa ancora la definizione di una funzione hash. (In pratica hai ragione, le funzioni hash che utilizziamo accettano input di lunghezza arbitraria, ma non credo che qualcosa non riesca a essere una funzione hash se non lo fa.)
Mike Ounsworth

@MikeOunsworth allo stesso modo posso avvolgerlo in modo tale che l'output sia troncato o imbottito se il msb è uno. L'output non ha più una lunghezza fissa, ma è ancora una funzione hash?
Smetti di fare del male a Monica il

@OrangeDog direi di no. Il mio punto da sempre è che una funzione hash deve essere mappata su un output di dimensioni fisse, ma la dimensione di input è irrilevante. Siamo diventati molto fuori tema. La tua risposta ha delle cose buone, fai solo attenzione alla tua definizione formale ;-)
Mike Ounsworth,

0

Ottima domanda Basil Ajith,

Ecco la mia prospettiva di cosa sia un hash per qualcosa a cui sto lavorando oggi.

*

Usa la somma di controllo per verificare che tarball sia congruente con la pagina di download

*

inserisci qui la descrizione dell'immagine Indossa il cappello da auditor, intendo la veste da mago

l'hash è un valore / stringa / qualunque / etichetta assicurati che sia lo stesso sul tuo computer come la fonte di un download.


3
Questo è solo un uso per un hash. Ci sono molti altri usi.
Yuval Filmus,

Benvenuti nel sito! L'uso di hash crittografici come checksum è già coperto dalla risposta accettata, quindi la tua risposta non aggiunge nulla di nuovo, occupando molto spazio sullo schermo.
David Richerby,

-1

Proverò solo ad aggiungere un breve riassunto di ciò che dicono gli altri.

Funzione hash

Esiste un tipo speciale di funzioni chiamate funzioni hash.

"SHA256 è una nota funzione hash crittograficamente sicura"

Tre applicazioni principali sono * tabelle hash, * checksum (controlli di integrità dei dati, ad esempio in dischi rigidi o protocolli ADSL), * e crittografia (varie forme di autenticazione crittografica, inclusi ma non limitati a firme digitali e archiviazione sicura delle password).

Hash table

La tabella hash è una struttura di dati per la ricerca veloce. Usa internamente le funzioni hash, da cui il nome.

"I database utilizzano tabelle hash e alberi di ricerca internamente per accelerare l'esecuzione delle richieste di ricerca"

hash

  1. un tipo di dati astratto del dizionario

"Hash" è il nome ufficiale dei dizionari incorporati in Perl. Sono tabelle di hash internamente, da cui il nome. "Questa subroutine accetta un hash come primo argomento". In questi giorni può essere utilizzato per qualsiasi array associativo, non necessariamente una tabella hash.

  1. risultato dell'applicazione di una funzione hash ad alcuni input

"Vengono forniti hash MD5 delle immagini .iso per verificarne l'integrità dopo il download".

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.