Ci proverò, dato che sono sufficientemente disturbato dal consiglio dato in alcune delle altre risposte.
Sia sequenze di bit infinite generate da due RNG (non necessariamente PRNG che sono deterministici una volta che lo stato iniziale è noto), e stiamo considerando la possibilità di usare la sequenza con la speranza di migliorare il comportamento in un certo senso. Esistono molti modi diversi in cui potrebbe essere considerato migliore o peggiore rispetto a ciascuno di e ; ecco una piccola manciata che ritengo significativa, utile e coerente con il normale uso delle parole "meglio" e "peggio":X⃗ ,Y⃗ X⃗ ⊕Y⃗ X⃗ ⊕Y⃗ X⃗ Y⃗
- (0) La probabilità di vera casualità della sequenza aumenta o diminuisce
- (1) Probabilità di aumenti o diminuzioni osservabili della non casualità (rispetto ad alcuni osservatori che applicano una determinata quantità di controllo, presumibilmente)
- (2) Gravità / ovvietà degli aumenti o delle diminuzioni osservabili della non casualità.
Per prima cosa pensiamo a (0), che è l'unico dei tre che ha qualche speranza di essere precisato. Si noti che se, in effetti, uno dei due RNG di input è veramente casuale, imparziale e indipendente dall'altro, anche il risultato XOR sarà davvero casuale e imparziale. Con questo in mente, considera il caso in cui credi che siano flussi di bit isolati imparziali veramente casuali, ma non sei completamente sicuro. Se sono le rispettive probabilità che ti sbagli su ciascuno di essi, allora la probabilità che non sia realmente casuale è quindi
, in effetti molto meno daX⃗ ,Y⃗ εX,εYX⃗ ⊕Y⃗ ≤εXεY<min{εX,εY}εX,εY sono considerati molto vicini a 0 ("credi che siano veramente casuali"). E in effetti è anche meglio di così, quando prendiamo in considerazione anche la possibilità che sia veramente indipendente anche quando nessuno dei due è veramente casuale:
Pertanto possiamo concludere che in senso (0), XOR non può far male e potrebbe potenzialmente aiutare molto.X⃗ ,Y⃗
Pr(X⃗ ⊕Y⃗ not truly random)≤min{Pr(X⃗ not truly random),Pr(Y⃗ not truly random),Pr(X⃗ ,Y⃗ dependent)}.
Tuttavia, (0) non è interessante per i PRNG, poiché nel caso dei PRNG nessuna delle sequenze in questione ha alcuna possibilità di essere veramente casuale.
Pertanto, per questa domanda, che in realtà riguarda i PRNG, dobbiamo parlare di qualcosa come (1) o (2). Dal momento che quelli sono in termini di proprietà e quantità come "osservabile", "grave", "ovvio", "apparente", ora stiamo parlando della complessità di Kolmogorov e non proverò a renderlo preciso. Ma andrò al punto di fare l'affermazione, si spera non controversa, che, con una misura del genere, "01100110 ..." (periodo = 4) sia peggiore di "01010101 ..." (periodo = 2) che è peggiore di " 00000000 ... "(costante).
Ora, si potrebbe supporre che (1) e (2) seguiranno la stessa tendenza di (0), e che quindi la conclusione "XOR non può far male" potrebbe continuare. Tuttavia, si noti la significativa possibilità che né né fossero osservabilmente non casuali, ma che le correlazioni tra loro causassero essere osservabilmente non casuali. Il caso più grave di questo, ovviamente, è quando (o ), nel qual caso è costante, il peggiore di tutti i risultati possibili; in generale, è facile vedere che, indipendentemente da quanto sono buoni e ,X⃗ Y⃗ X⃗ ⊕Y⃗ X⃗ =Y⃗ X⃗ =not(Y⃗ )X⃗ ⊕Y⃗ X⃗ Y⃗ X⃗ e devono essere "vicini" a indipendenti affinché il loro xor sia non osservabilmente non casuale. In effetti, essere non-osservabilmente-dipendente può ragionevolmente essere definito come non-osservabilmente-non casuale.Y⃗ X⃗ ⊕Y⃗
Tale dipendenza a sorpresa si rivela essere un grosso problema.
Un esempio di cosa non va
La domanda afferma "Sto escludendo l'esempio comune di diversi registri a scorrimento con feedback lineare che lavorano insieme poiché appartengono alla stessa famiglia". Ma per il momento escluderò tale esclusione, al fine di fornire un esempio molto semplice e chiaro della vita reale del tipo di cose che possono andare storte con XORing.
Il mio esempio sarà una vecchia implementazione di rand () che era su una versione di Unix intorno al 1983. IIRC, questa implementazione della funzione rand () aveva le seguenti proprietà:
- il valore di ogni chiamata a rand () era 15 bit pseudo-casuali, ovvero un numero intero nell'intervallo [0, 32767).
- valori di ritorno successivi si alternano pari-dispari-pari-dispari; cioè il bit meno significativo alternato 0-1-0-1 ...
- il bit meno significativo aveva il periodo 4, il successivo dopo aveva il periodo 8, ... quindi il bit di ordine più alto aveva il periodo .215
- pertanto la sequenza dei valori di ritorno a 15 bit di rand () era periodica con il periodo .215
Non sono stato in grado di individuare il codice sorgente originale, ma immagino di mettere insieme un paio di post in https://groups.google.com/forum/#!topic/comp.os.vms/9k4W6KrRV3A che ha fatto esattamente il seguente (codice C), che concorda con la mia memoria delle proprietà sopra:
#define RAND_MAX 32767
static unsigned int next = 1;
int rand(void)
{
next = next * 1103515245 + 12345;
return (next & RAND_MAX);
}
void srand(seed)
unsigned int seed;
{
next = seed;
}
Come si potrebbe immaginare, provare a usare questo rand () in vari modi ha portato a un assortimento di delusioni.
Ad esempio, ad un certo punto ho provato a simulare una sequenza di lanci di monete casuali prendendo ripetutamente:
rand() & 1
cioè il bit meno significativo. Il risultato fu una semplice alternanza testa-coda-testa-coda. All'inizio era difficile da credere (deve essere un bug nel mio programma!), Ma dopo essermi convinto che fosse vero, ho provato invece a usare il bit meno significativo successivo. Non è molto meglio, come notato in precedenza, quel bit è periodico con il periodo 4. Continuando ad esplorare bit successivamente più alti ha rivelato lo schema che ho notato prima: cioè, ogni successivo bit di ordine superiore aveva il doppio del periodo del precedente, quindi in questo rispetto il bit di ordine più elevato è stato il più utile di tutti. Si noti tuttavia che non esiste una soglia in bianco e nero "bit è utile, bit non è utile" qui; tutto ciò che possiamo veramente dire è che le posizioni dei bit numerate avevano vari gradi di utilità / inutilità.ii−1
Ho anche provato cose come confondere ulteriormente i risultati o XORing insieme valori restituiti da più chiamate a rand (). XORing coppie di valori rand () successivi è stato ovviamente un disastro, ha provocato tutti i numeri dispari! Per i miei scopi (ovvero produrre una sequenza "apparentemente casuale" di lanci di monete), il risultato di parità costante della XOR era persino peggiore del comportamento dispari alternato dell'originale.
Una leggera variazione lo inserisce nel framework originale: vale a dire che sia la sequenza di valori a 15 bit restituiti da rand () con un dato seed e la sequenza da un seed diverso . Ancora una volta, sarà una sequenza di numeri pari o dispari, che è peggiore del comportamento pari / dispari alternato originale.X⃗ sXY⃗ sYX⃗ ⊕Y⃗
In altre parole, questo è un esempio in cui XOR ha peggiorato le cose nel senso di (1) e (2), con qualsiasi interpretazione ragionevole. È peggio anche in molti altri modi:
- (3) Il bit meno significativo di XOR è ovviamente distorto, cioè ha frequenze disuguali di 0 e 1, a differenza di qualsiasi posizione di bit numerata in uno degli ingressi che sono tutti imparziali.
- (4) In effetti, per ogni posizione di bit, ci sono coppie di semi per le quali tale posizione di bit è distorta nel risultato XOR e per ogni coppia di semi, ci sono (almeno 5) posizioni di bit che sono polarizzate in XOR risultato.
- (5) Il periodo dell'intera sequenza di valori a 15 bit nel risultato XOR è 1 o , rispetto a per gli originali.214215
Nessuno di (3), (4), (5) è ovvio, ma sono tutti facilmente verificabili.
Infine, consideriamo di reintrodurre il divieto di PRNG della stessa famiglia. Il problema qui, penso, è che non è mai veramente chiaro se due PRNG siano "della stessa famiglia", fino a quando / a meno che qualcuno non inizi a usare l'XOR e noti (o nota un attaccante) le cose peggiorano nel senso di (1) e (2), cioè fino a quando i pattern non casuali nell'output attraversano la soglia da non notato a notato / imbarazzante / disastroso, e a quel punto è troppo tardi.
Sono allarmato da altre risposte qui che danno consigli non qualificati "XOR non può far male" sulla base di misure teoriche che mi sembrano fare un cattivo lavoro nel modellare ciò che la maggior parte della gente considera "buona" e "cattiva" riguardo PRNG nella vita reale. Tale consiglio è contraddetto da esempi chiari e sfacciati in cui XOR peggiora le cose, come l'esempio rand () di cui sopra. Mentre è immaginabile che PRNG relativamente "forti" possano mostrare costantemente il comportamento opposto quando XOR rispetto a quello del PRNG giocattolo che era rand (), rendendo così XOR una buona idea per loro, non ho visto prove in quella direzione, teorica o empirico, quindi mi sembra irragionevole supporre che ciò accada.
Personalmente, dopo essere stato morso a sorpresa da XORing rand () s in gioventù e da innumerevoli altre correlazioni a sorpresa assortite nel corso della mia vita, ho poche ragioni per pensare che il risultato sarà diverso se provo di nuovo tattiche simili. Questo è il motivo per cui, personalmente, sarei molto riluttante a XOR insieme a PRNG multipli a meno che non siano state condotte analisi e controlli molto approfonditi per darmi la certezza che potrebbe essere sicuro farlo per i particolari RNG in questione. Come potenziale cura per quando ho scarsa fiducia in uno o più dei singoli PRNG, è improbabile che XORing aumenti la mia fiducia, quindi è improbabile che lo utilizzi per tale scopo. Immagino che la risposta alla tua domanda sia che questo è un sentimento ampiamente diffuso.