Funzione che diffonde l'input


14

Vorrei sapere se esiste una funzione f da numeri n-bit a numeri n-bit che presenta le seguenti caratteristiche:

  • f dovrebbe essere biiettivo
  • Sia f che f1 dovrebbero essere calcolabili abbastanza velocemente
  • f dovrebbe restituire un numero che non ha correlazioni significative con il suo input.

La logica è questa:

Voglio scrivere un programma che funziona sui dati. Alcune informazioni dei dati sono archiviate in un albero di ricerca binario in cui la chiave di ricerca è un simbolo di un alfabeto. Con il tempo, aggiungo ulteriori simboli all'alfabeto. Nuovi simboli ottengono semplicemente il prossimo numero gratuito disponibile. Quindi, l'albero avrà sempre una leggera propensione per le chiavi più piccole, il che provoca più riequilibrazioni di quanto ritenga necessario.

La mia idea è quella di manipolare i numeri dei simboli con f tale che siano ampiamente diffusi su tutta la gamma di [0,2641] . Poiché i numeri dei simboli sono importanti solo durante l'input e l'output, che si verificano una sola volta, l'applicazione di tale funzione non dovrebbe essere troppo costosa.

Ho pensato a un'iterazione del generatore di numeri casuali Xorshift, ma non conosco davvero un modo per annullarlo, anche se teoricamente dovrebbe essere possibile.

Qualcuno conosce una tale funzione?
E 'questa una buona idea?


1
Non sono un esperto, ma forse puoi usare una permutazione pseudocasuale (vedi ad esempio il codice Feistel )
Vor

Se stai essenzialmente calcolando una funzione hash, perché non usare l'hash?
vonbrand,

@vonbrand Hashing non è reversibile. Vedi requisito numero 2.
FUZxxl,

Perché deve essere reversibile? Cosa c'è di sbagliato nel renderlo reversibile dalla ricerca?
vonbrand,

1
È possibile memorizzare (f (x), x) come chiavi.
adrianN,

Risposte:


6

Puoi usare l' hashing di Fibonacci , in particolare

.hF(k)=k512k512

Per ottieni n numeri distinti in modo a coppie (circa) distribuiti uniformemente in [ 0 , 1 ] . Scalando a [ 1 .. M ] e arrotondando (verso il basso), si ottiene una distribuzione uniforme dei numeri in quell'intervallo.k=1,,nn[0,1][1..M]

Ad esempio, questi sono ridimensionati su [ 0..10000 ] (sequenza originale a sinistra, ordinata a destra):hF(1),,hF(200)[0..10000]

inserisci qui la descrizione dell'immagine

Questa è un'istanza di ciò che Knuth chiama hashing moltiplicativo . Per la dimensione della parola del computer, A un numero intero relativamente primo per w e M il numero di indirizzi necessari, usiamowAwM

h(k)=M((kAw)mod1)

come funzione di hashing. Quanto sopra segue con (assicurati di poterlo calcolare con una precisione sufficiente). Mentre questo funziona anche con qualsiasi altro numero irrazionale oltre aϕ-1, è uno dei due soli numeri che portano ai numeri "distribuiti in modo più uniforme".A/w=ϕ1=512ϕ1

Scopri di più in The Art of Computer Programming , Volume 3 di Donald Knuth (capitolo 6.4 da pagina 513 della seconda edizione). In particolare, scoprirai perché i numeri risultanti sono distinti a coppie (almeno se ) e come calcolare la funzione inversa se usi A e w naturali invece di ϕ - 1 .nMAwϕ1


1
Come calcolare efficiente? f1
frafl

1
@frafl Spero che la mia modifica risolva in qualche modo la tua preoccupazione. È chiaro, tuttavia, che queste tecniche di hashing non sono né particolarmente progettate per essere invertibili in modo efficiente.
Raffaello

Sì, lo voterò, tuttavia non lo consiglierei come risposta accettata.
frafl

1

Per ingressi -bit, questa funzione:k

hash(n)=(nmod2k2)2k2+ndiv2k2

Questo è reversibile, in quanto , e ha coppie non sequenziali { n , m } , n < m , dove h a s h ( m ) < h a s h ( n ) . Attenzione che l'output e l'input possono essere correlati, specialmente se l'input è in { 1 , ... , 2 khash(hash(n))=n{n,m},n<mhash(m)<hash(n).{1,,2k21}

Rif: funzione hash reversibile


Sembra semplice e carino. Lo proverò.
FUZxxl

1
1ρ

è abbastanza chiaro! per 64 bit (0x00000000FFFFFFFF) e dovresti spostare (<<) 32 bit. Questa funzione è semplice, pratica e abbastanza veloce nella pratica.
Reza

1
x{1,,2321}232x
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.