Come funziona un hash percettivo
Salva di nuovo una foto e il suo SHA-256 cambia da cima a fondo, pur essendo — a occhio — la stessa identica immagine. È il comportamento corretto di un hash crittografico, ed è esattamente ciò che lo rende inutile per rispondere alla domanda che ti stai facendo: «questa è la stessa foto di quella?»
Il problema, in un esempio
Prendi una fotografia. Aprila, salvala con qualità 80 invece che 95. Il contenuto visivo è indistinguibile, ma i byte sono un'altra cosa: la compressione JPEG ha ricalcolato ogni blocco. E l'hash crittografico, che per progetto amplifica qualsiasi differenza di un bit fino a stravolgere metà del digest, ti dice che i due file non hanno nulla in comune.
Ha ragione. I due file non hanno nulla in comune. Ma tu non stavi chiedendo dei file.
L'idea: rovesciare l'effetto valanga
Un hash percettivo è costruito con l'obiettivo opposto a quello di SHA-256. Vuole che a piccole variazioni dell'immagine corrispondano piccole variazioni dell'impronta. Non è più una funzione a senso unico: è una funzione che comprime l'aspetto visivo in poche decine di bit, buttando via tutto ciò che l'occhio non registra — il rumore, i dettagli fini, le microdifferenze di compressione — e conservando ciò che resta.
Il procedimento è sempre lo stesso, qualunque sia l'algoritmo:
- Riduci l'immagine a una griglia minuscola, tipicamente 8×8 pixel. Sparisce ogni dettaglio: resta la struttura di luci e ombre.
- Converti in scala di grigi. Il colore, per questi algoritmi, è rumore.
- Confronta ogni cella con una soglia (la media, il pixel accanto, la mediana dei coefficienti). Il risultato di ogni confronto è un bit: 1 o 0.
- Concatena i bit. Sessantaquattro confronti, sessantaquattro bit: è l'impronta percettiva.
Ridimensionare, ricomprimere, cambiare formato: nessuna di queste operazioni sposta significativamente le luci e le ombre della griglia 8×8. Quindi nessuna di queste operazioni cambia più di qualche bit.
Come si legge il risultato: la distanza di Hamming
Due impronte percettive non si confrontano chiedendo «sono uguali?». Si confrontano contando quanti bit differiscono. Quel numero si chiama distanza di Hamming, e ha un significato immediato: quante delle sessantaquattro domande sulla struttura dell'immagine hanno ricevuto risposta diversa.
Probatio la traduce anche in percentuale, con una formula che è esattamente quello che sembra:
similarità = (1 − distanza ÷ bit totali) × 100
Due impronte a 64 bit che differiscono per 2 bit danno 96,9% di similarità. Se ne differiscono 32 — cioè metà, il valore atteso fra due immagini scelte a caso — la similarità è 50%, che è il modo tecnico per dire «nessuna relazione».
Nessun verdetto automatico, ed è un pregio
Molti strumenti sputano un «match / no match» basato su una soglia scelta da qualcun altro. Probatio no: il confronto immagini restituisce, per ciascuno dei tre algoritmi (aHash, dHash, pHash), l'impronta di entrambe le immagini, la distanza di Hamming e la similarità percentuale.
La ragione è processuale, prima ancora che tecnica. Una soglia è una decisione, e in una relazione tecnica le decisioni si dichiarano e si giustificano. Scrivere «lo strumento ha detto match» è indifendibile; scrivere «le due immagini distano 4 bit su 64 su tutti e tre gli algoritmi, valore compatibile con una ricompressione e incompatibile con soggetti diversi» è un'affermazione che regge al controesame.
Profondità: 64, 144 o 256 bit
Probatio calcola le impronte a tre profondità, corrispondenti a griglie 8×8, 12×12 e 16×16.
- 64 bit è il valore classico, adatto a ritrovare la stessa immagine dopo ricompressione o ridimensionamento. È tollerante, anche troppo su immagini molto simili tra loro.
- 144 e 256 bit conservano più struttura, distinguono meglio immagini che si assomigliano (per esempio due fotogrammi consecutivi di un video), ma diventano più sensibili a ritagli e rotazioni.
Non esiste la scelta giusta in assoluto. Esiste la scelta giusta rispetto alla domanda: ritrovare un'immagine chiede tolleranza, distinguere due immagini simili chiede risoluzione.
Quello che un hash percettivo non fa
- Non è una prova di identità. Due immagini con distanza zero sono visivamente indistinguibili alla risoluzione della griglia, non necessariamente identiche. Per l'identità c'è SHA-256.
- Non è a senso unico. Dall'impronta si ricava una vaghissima idea della distribuzione di luci e ombre. Non trattarla come un dato anonimo.
- Non resiste a un avversario. Chi conosce l'algoritmo può costruire un'immagine con l'impronta che vuole. Serve a cercare, non a sigillare.
- Non ragiona sul contenuto. Non sa cosa raffigura l'immagine. Vede una griglia di grigi.
Nel fascicolo convivono benissimo: SHA-256 sigilla il file, l'hash percettivo ritrova l'immagine. La prima domanda è «è stato alterato?». La seconda è «l'abbiamo già vista?». Confonderle è il modo più rapido per rispondere male a entrambe.