Le daré una oportunidad a esto, ya que estoy suficientemente perturbado por el consejo dado en algunas de las otras respuestas.
Deje que sean secuencias de bits infinitas generadas por dos RNG (no necesariamente PRNG que son deterministas una vez que se conoce el estado inicial), y estamos considerando la posibilidad de usar la secuencia con la esperanza de mejorar el comportamiento en algún sentido. Hay muchas formas diferentes en que podría considerarse mejor o peor en comparación con cada uno de y ; Aquí hay un pequeño puñado que creo que es significativo, útil y consistente con el uso normal de las palabras "mejor" y "peor":X⃗ ,Y⃗ X⃗ ⊕Y⃗ X⃗ ⊕Y⃗ X⃗ Y⃗
- (0) La probabilidad de aleatoriedad verdadera de la secuencia aumenta o disminuye
- (1) La probabilidad de no observabilidad aleatoria aumenta o disminuye (con respecto a algún observador que aplica cierta cantidad de escrutinio, presumiblemente)
- (2) La gravedad / evidencia de la no aleatoriedad observable aumenta o disminuye.
Primero pensemos en (0), que es el único de los tres que tiene alguna esperanza de ser preciso. Tenga en cuenta que si, de hecho, cualquiera de los dos RNG de entrada es realmente aleatorio, imparcial e independiente del otro, entonces el resultado XOR será realmente aleatorio e imparcial también. Con eso en mente, considere el caso cuando cree que son flujos de bits aislados verdaderamente aleatorios e imparciales, pero no está completamente seguro. Si son las probabilidades respectivas de que esté equivocado acerca de cada uno de ellos, entonces la probabilidad de que no sea realmente aleatorio es entonces
, de hecho mucho menos desdeX⃗ ,Y⃗ εX,εYX⃗ ⊕Y⃗ ≤εXεY<min{εX,εY}εX,εYSe supone que están muy cerca de 0 ("usted cree que son verdaderamente aleatorios"). Y, de hecho, es incluso mejor que eso, cuando también tenemos en cuenta la posibilidad de que sea verdaderamente independiente, incluso cuando ninguno de los dos sea verdaderamente aleatorio:
Por lo tanto, podemos concluir que en el sentido (0), XOR no puede hacer daño, y podría ayudar mucho.X⃗ ,Y⃗
Pr(X⃗ ⊕Y⃗ not truly random)≤min{Pr(X⃗ not truly random),Pr(Y⃗ not truly random),Pr(X⃗ ,Y⃗ dependent)}.
Sin embargo, (0) no es interesante para los PRNG, ya que en el caso de los PRNG ninguna de las secuencias en cuestión tiene ninguna posibilidad de ser realmente aleatoria.
Por lo tanto, para esta pregunta, que de hecho se trata de PRNG, debemos estar hablando de algo como (1) o (2). Dado que se trata de propiedades y cantidades como "observable", "grave", "obvio", "aparente", ahora estamos hablando de la complejidad de Kolmogorov, y no voy a tratar de precisar eso. Pero iré tan lejos como para hacer la afirmación esperanzadora de que, según tal medida, "01100110 ..." (período = 4) es peor que "01010101 ..." (período = 2) que es peor que " 00000000 ... "(constante).
Ahora, uno podría adivinar que (1) y (2) seguirán la misma tendencia que (0), y que por lo tanto, la conclusión "XOR no puede doler" aún podría mantenerse. Sin embargo, tenga en cuenta la posibilidad significativa de que ni ni fueran observablemente no aleatorios, sino que las correlaciones entre ellos hacen que sea observablemente no aleatorio. El caso más grave de esto, por supuesto, es cuando (o ), en cuyo caso es constante, el peor de todos los resultados posibles; en general, es fácil ver que, independientemente de lo buenos que sean y ,X⃗ Y⃗ X⃗ ⊕Y⃗ X⃗ =Y⃗ X⃗ =not(Y⃗ )X⃗ ⊕Y⃗ X⃗ Y⃗ X⃗ y necesitan estar "cerca" de ser independientes para que su xor sea no observable-no aleatorio. De hecho, ser dependiente no observable puede definirse razonablemente como siendo no observable-no aleatorio.Y⃗ X⃗ ⊕Y⃗
Tal dependencia sorpresa resulta ser un gran problema.
Un ejemplo de lo que sale mal
La pregunta dice "Estoy excluyendo el ejemplo común de varios registros de desplazamiento de retroalimentación lineal que trabajan juntos ya que son de la misma familia". Pero voy a excluir esa exclusión por el momento, para dar un ejemplo muy simple y claro de la vida real del tipo de cosas que pueden salir mal con XORing.
Mi ejemplo será una implementación antigua de rand () que estaba en alguna versión de Unix alrededor de 1983. IIRC, esta implementación de la función rand () tenía las siguientes propiedades:
- el valor de cada llamada a rand () fue de 15 bits pseudoaleatorios, es decir, un número entero en el rango [0, 32767).
- valores de retorno sucesivos alternados pares-impares-pares-impares; es decir, el bit menos significativo alternado 0-1-0-1 ...
- el siguiente bit menos significativo tuvo el período 4, el siguiente después del período 8, ... así que el bit de orden más alto tuvo el período .215
- por lo tanto, la secuencia de valores de retorno de 15 bits de rand () fue periódica con el período .215
No he podido localizar el código fuente original, pero supongo que al juntar un par de publicaciones en https://groups.google.com/forum/#!topic/comp.os.vms/9k4W6KrRV3A que hizo precisamente lo siguiente (código C), que concuerda con mi memoria de las propiedades anteriores:
#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;
}
Como uno podría imaginar, tratar de usar este rand () de varias maneras condujo a una variedad de decepciones.
Por ejemplo, en un momento intenté simular una secuencia de lanzamientos aleatorios de monedas al tomar repetidamente:
rand() & 1
es decir, el bit menos significativo. El resultado fue una simple alternancia cabeza-cruz-cabeza-cruz. Al principio fue difícil de creer (¡debe ser un error en mi programa!), Pero después de convencerme de que era cierto, intenté usar el siguiente bit menos significativo. Eso no es mucho mejor, como se señaló anteriormente: ese bit es periódico con el período 4. Continuar explorando bits sucesivamente más altos reveló el patrón que noté anteriormente: es decir, cada siguiente bit de orden superior tenía el doble del período del anterior, así que en A este respecto, el bit de orden superior fue el más útil de todos. Sin embargo, tenga en cuenta que aquí no había un umbral en blanco y negro "el bit es útil, el bit no es útil"; todo lo que realmente podemos decir es que las posiciones de bits numeradas tenían diversos grados de utilidad / inutilidad.ii−1
También probé cosas como codificar aún más los resultados o XORing juntos los valores devueltos de múltiples llamadas a rand (). XORing pares de valores sucesivos de rand () fue un desastre, por supuesto, ¡resultó en todos los números impares! Para mis propósitos (es decir, producir una secuencia "aparentemente aleatoria" de lanzamientos de monedas), el resultado de paridad constante del XOR fue incluso peor que el comportamiento alterno par-impar del original.
Una ligera variación pone esto en el marco original: es decir, que sea la secuencia de valores de 15 bits devueltos por rand () con una semilla dada , y la secuencia de una semilla diferente . Nuevamente, será una secuencia de números pares o impares, que es peor que el comportamiento alternativo par / impar original.X⃗ sXY⃗ sYX⃗ ⊕Y⃗
En otras palabras, este es un ejemplo donde XOR empeoró las cosas en el sentido de (1) y (2), por cualquier interpretación razonable. También es peor en otras formas:
- (3) El bit menos significativo XORed está obviamente sesgado, es decir, tiene frecuencias desiguales de 0 y 1, a diferencia de cualquier posición de bit numerada en cualquiera de las entradas que son todas imparciales.
- (4) De hecho, para cada posición de bit, hay pares de semillas para las cuales esa posición de bit está sesgada en el resultado XOR, y para cada par de semillas, hay (al menos 5) posiciones de bit que están sesgadas en el XOR resultado.
- (5) El período de toda la secuencia de valores de 15 bits en el resultado XOR es 1 o , en comparación con para los originales.214215
Ninguno de (3), (4), (5) es obvio, pero todos son fácilmente verificables.
Finalmente, consideremos reintroducir la prohibición de los PRNG de la misma familia. El problema aquí, creo, es que nunca está realmente claro si dos PRNG son "de la misma familia", hasta que / a menos que alguien comience a usar el XOR y se dé cuenta (o un atacante) que las cosas empeoraron en el sentido de (1) y (2), es decir, hasta que los patrones no aleatorios en la salida crucen el umbral de no notado a notado / vergonzoso / desastroso, y en ese punto es demasiado tarde.
Estoy alarmado por otras respuestas aquí que dan consejos no calificados "XOR no puede hacer daño" sobre la base de medidas teóricas que me parecen hacer un mal trabajo de modelar lo que la mayoría de la gente considera "bueno" y "malo" sobre PRNG en la vida real. Ese consejo se contradice con ejemplos claros y descarados en los que XOR empeora las cosas, como el ejemplo de rand () dado anteriormente. Si bien es concebible que los PRNG relativamente "fuertes" puedan mostrar consistentemente el comportamiento opuesto cuando XOR se acerca al del PRNG de juguete que era rand (), lo que hace que XOR sea una buena idea para ellos, no he visto evidencia en esa dirección, teórica o empírica, por lo que me parece irrazonable suponer que eso sucede.
Personalmente, habiendo sido mordido por sorpresa por XORing rand () s en mi juventud, y por innumerables otras correlaciones sorpresa variadas a lo largo de mi vida, tengo pocas razones para pensar que el resultado será diferente si vuelvo a intentar tácticas similares. Es por eso que yo, personalmente, sería muy reacio a XOR juntos múltiples PRNG a menos que se hayan realizado análisis y análisis exhaustivos para darme cierta confianza de que podría ser seguro hacerlo para los RNG en cuestión. Como una posible cura para cuando tengo poca confianza en uno o más de los PRNG individuales, es poco probable que XORing aumente mi confianza, por lo que es poco probable que lo use para tal fin. Me imagino que la respuesta a su pregunta es que este es un sentimiento muy extendido.