Alex lo ha spiegato abbastanza bene. Per coloro che ancora non l'hanno capito, si spera che questo esempio ti aiuti a capire:
Diciamo che lavoro per Google, nel team di Chrome, e voglio aggiungere una funzionalità al browser che avvisa l'utente se l'URL che ha inserito è un URL dannoso. Quindi ho un set di dati di circa 1 milione di URL dannosi, la dimensione di questo file è di circa 25 MB. Poiché la dimensione è abbastanza grande (grande rispetto alla dimensione del browser stesso), memorizzo questi dati su un server remoto.
Caso 1: utilizzo una funzione hash con una tabella hash. Decido su una funzione di hashing efficiente ed eseguo tutti i 1 milione di URL attraverso la funzione di hashing per ottenere chiavi hash. Quindi creo una tabella hash (un array), dove la chiave hash mi darebbe l'indice per posizionare quell'URL. Quindi ora una volta che ho eseguito l'hashing e ho riempito la tabella di hashing, ne controllo le dimensioni. Ho memorizzato tutti 1 milione di URL nella tabella hash insieme alle loro chiavi. Quindi la dimensione è di almeno 25 MB. Questa tabella hash, a causa delle sue dimensioni, verrà archiviata su un server remoto. Quando un utente arriva e inserisce un URL nella barra degli indirizzi, devo controllare se è dannoso. Quindi eseguo l'URL attraverso la funzione hash (il browser stesso può farlo) e ottengo una chiave hash per quell'URL. Ora devo fare una richiesta al mio server remoto con quella chiave hash, per verificare se l'URL particolare nella mia tabella hash con quella particolare chiave, è lo stesso di quello che l'utente ha inserito. Se sì, allora è dannoso e in caso negativo non è dannoso. Pertanto, ogni volta che l'utente immette un URL, deve essere effettuata una richiesta al server remoto per verificare se si tratta di un URL dannoso. Ciò richiederebbe molto tempo e quindi rallenterebbe il mio browser.
Caso 2: utilizzo un filtro bloom. L'intero elenco di 1 milione di URL viene eseguito attraverso il filtro bloom utilizzando più funzioni hash e le rispettive posizioni sono contrassegnate come 1, in una vasta gamma di 0. Supponiamo di volere un tasso di falsi positivi dell'1%, utilizzando un calcolatore del filtro bloom ( http://hur.st/bloomfilter?n=1000000&p=0.01), otteniamo la dimensione del filtro bloom richiesto di soli 1,13 MB. Questa piccola dimensione è prevista poiché, anche se la dimensione dell'array è enorme, stiamo memorizzando solo 1 o 0 e non gli URL come nel caso della tabella hash. Questo array può essere trattato come un array di bit. Cioè, poiché abbiamo solo due valori 1 e 0, possiamo impostare singoli bit invece di byte. Ciò ridurrebbe lo spazio occupato di 8 volte. Questo filtro bloom da 1,13 MB, a causa delle sue piccole dimensioni, può essere memorizzato nel browser web stesso !! Pertanto, quando un utente arriva e inserisce un URL, applichiamo semplicemente le funzioni hash richieste (nel browser stesso) e controlliamo tutte le posizioni nel filtro bloom (che è memorizzato nel browser). Un valore 0 in una qualsiasi delle posizioni ci dice che questo URL NON è SICURAMENTE nell'elenco degli URL dannosi e l'utente può procedere liberamente. Pertanto non abbiamo effettuato una chiamata al server e quindi abbiamo risparmiato tempo. Un valore di 1 ci dice che l'URL POTREBBE essere nell'elenco di URL dannosi. In questi casi facciamo una chiamata al server remoto e da lì possiamo usare qualche altra funzione hash con qualche tabella hash come nel primo caso per recuperare e controllare se l'URL è effettivamente presente. Poiché la maggior parte delle volte, è improbabile che un URL sia dannoso, il piccolo filtro bloom nel browser lo capisce e quindi fa risparmiare tempo evitando le chiamate al server remoto. Solo in alcuni casi, se il filtro bloom ci dice che l'URL POTREBBE essere dannoso, solo in quei casi effettuiamo una chiamata al server. Quel "MIGHT" è corretto al 99%. In questi casi facciamo una chiamata al server remoto e da lì possiamo usare qualche altra funzione hash con qualche tabella hash come nel primo caso per recuperare e controllare se l'URL è effettivamente presente. Poiché la maggior parte delle volte, è improbabile che un URL sia dannoso, il piccolo filtro bloom nel browser lo capisce e quindi fa risparmiare tempo evitando le chiamate al server remoto. Solo in alcuni casi, se il filtro bloom ci dice che l'URL POTREBBE essere dannoso, solo in quei casi effettuiamo una chiamata al server. Quel "MIGHT" è corretto al 99%. In questi casi facciamo una chiamata al server remoto e da lì possiamo usare qualche altra funzione hash con qualche tabella hash come nel primo caso per recuperare e controllare se l'URL è effettivamente presente. Poiché la maggior parte delle volte, è improbabile che un URL sia dannoso, il piccolo filtro bloom nel browser lo capisce e quindi fa risparmiare tempo evitando le chiamate al server remoto. Solo in alcuni casi, se il filtro bloom ci dice che l'URL POTREBBE essere dannoso, solo in quei casi effettuiamo una chiamata al server. Quel "MIGHT" è corretto al 99%. il piccolo filtro bloom nel browser lo capisce e quindi fa risparmiare tempo evitando le chiamate al server remoto. Solo in alcuni casi, se il filtro bloom ci dice che l'URL POTREBBE essere dannoso, solo in quei casi effettuiamo una chiamata al server. Quel "MIGHT" è corretto al 99%. il piccolo filtro bloom nel browser lo capisce e quindi fa risparmiare tempo evitando le chiamate al server remoto. Solo in alcuni casi, se il filtro bloom ci dice che l'URL POTREBBE essere dannoso, solo in quei casi effettuiamo una chiamata al server. Quel "MIGHT" è corretto al 99%.
Quindi, utilizzando un piccolo filtro bloom nel browser, abbiamo risparmiato molto tempo poiché non è necessario effettuare chiamate al server per ogni URL inserito.
Possiamo vedere che la tabella hash con una singola funzione hash viene utilizzata per uno scopo completamente diverso rispetto a un filtro bloom. Spero che questo chiarisca i tuoi dubbi :)
modifica :
Ho implementato un filtro bloom per l'attività di test di URL dannosi in Python. Il codice può essere trovato qui - https://github.com/tarunsharma1/Bloom-Filter
Il codice è molto semplice da capire e una descrizione dettagliata è fornita nel file readme.