Perché std :: hash non è garantito per essere deterministico?


28

Di seguito, utilizziamo N4140 (standard C ++ 14).


In base al § 17.6.3.4 Requisiti di hash ,

Il valore restituito dipende solo dall'argomento k per la durata del programma .

[Nota: pertanto tutte le valutazioni dell'espressione h(k)con lo stesso valore per kproducono lo stesso risultato per una data esecuzione del programma . - nota finale]

e dice l' hash del modello di classe 20.9.12

...

l'istanza hash<Key>deve:

(1.1) - soddisfa i requisiti Hash (17.6.3.4) ...

(1.2) - ...


Ciò significa che un valore di hash di value(ovvero hash<decltype(value)>(value)) può assumere un valore diverso se si riavvia il programma.

Ma perché? Questa limitazione non era nello standard di C ++ 11, ma nello standard di C ++ 14, C ++ 17 e C ++ 20. Come utente (non uno sviluppatore STL), sarebbe piuttosto utile se std::hashfosse deterministico. Ci sono difficoltà matematiche nell'implementazione di una funzione hash deterministica? Ma le funzioni hash che utilizziamo quotidianamente (ad es. Deprecate md5sumo più sicure sha256) sono tutte deterministiche. C'è un problema di efficienza?


7
"... Le funzioni di hash sono richieste solo per produrre lo stesso risultato per lo stesso input all'interno di una singola esecuzione di un programma; questo consente hash salati che impediscono attacchi di negazione del servizio di collisione ." fonte: en.cppreference.com/w/cpp/utility/hash
Richard Critten del

5
Consente a un algoritmo deterministico di accettare input non deterministici. Valori puntatore, ad esempio. Una struttura di dati immutabile potrebbe eseguire l'hashing degli indirizzi dei suoi dati interni, il che potrebbe essere molto più veloce dell'hashing dei contenuti.
John Kugelman,

4
Questa risposta contiene alcuni buoni collegamenti per il motivo per cui non si vorrebbe determinismo.
NathanOliver

3
Non minacciarlo come una limitazione, ma rendere i vincoli standard un po 'meno severi.
Marek R

4
Ecco una spiegazione completa del perché i vincoli sono stati allentati.
Marek R,

Risposte:


17

Non è necessario che la funzione hash sia deterministica tra le esecuzioni, ma è comunque possibile fornire il proprio hash, ad esempio per i contenitori non ordinati se si tratta di un comportamento su cui si fa affidamento.

Per quanto riguarda il motivo, cppreference dice:

Le funzioni hash sono richieste solo per produrre lo stesso risultato per lo stesso input all'interno di una singola esecuzione di un programma; ciò consente hash salati che impediscono gli attacchi di negazione del servizio di collisione.

Se i Hashrequisiti indicano che è deterministico, non saresti in grado di fornire un hash salato senza infrangere il requisito.

Ecco la vera spiegazione del perché


7

Questa risposta (e collegamenti in essa) suggerita da @NathanOliver è in definitiva utile. Vorrei citare parti importanti.

Per una funzione hash non crittografica, è possibile pre-calcolare input massicci con lo stesso valore hash per rallentare algoritmicamente i contenitori non ordinati e provocare un attacco denial-of-service.

(dal numero 2291. std :: hash è vulnerabile agli attacchi DoS di collisione )

Per questo motivo, i progettisti del linguaggio stanno migrando verso l'hash casuale. Nell'hash casuale, il valore di hash della stringa "a" può cambiare ogni volta che si esegue il programma. L'hash casuale è ora predefinito in Python (dalla versione 3.3), Ruby (dalla versione 1.9) e Perl (dalla versione 5.18).

(da Ti rendi conto che stai usando l'hash casuale? )

Passa a Pronto, piuttosto che immediato, poiché anche l'autorizzazione è stata controversa nella discussione sul riflettore

(dal numero 2291. std :: hash è vulnerabile agli attacchi DoS di collisione )

In pratica, per quanto ho capito, nessuna implementazione di std::hashhash casuale implementa ma puoi scrivere il tuo my::secure_hash.

(da questa risposta )


PS

Ho appena cercato su Google "hash table dos" e ho trovato una pagina informativa: il momento in cui ti rendi conto che ogni server nel mondo è vulnerabile .

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.