Cómo aplicar ingeniería inversa a str_shuffle (PHP) para obtener sus salidas mt_rand

1
$output = str_shuffle("12345");

Por ejemplo, $output ahora es 25134 ¿Cómo puedo saber qué números salieron de mt_rand() para permitir la reproducción aleatoria? Quiero saber esto porque quiero que la semilla de mt_rand() y str_shuffle() use mt_rand() que no es criptográficamente segura ya que usa Mersenne Twister (Wikipedia) Sé que shuffle for python está usando Fisher Yates shuffle (Wikipedia) pero no tengo idea de cómo funciona en php. puede obtener la semilla utilizada si tiene 624 salidas usando mersenne-twister-recover (GitHub) o puede brutar forzar la semilla con untwister (GitHub)

    
pregunta OfficialNoob 29.06.2018 - 17:00
fuente

1 respuesta

1

Según PHP 7.2.7 fuentes , La función str_shuffle utiliza php_string_shuffle que hace

while (--n_left) {
    rnd_idx = php_rand();
    RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX);
    if (rnd_idx != n_left) {
        temp = str[n_left];
        str[n_left] = str[rnd_idx];
        str[rnd_idx] = temp;
    }
}

Supongo que le gustaría saber los valores intermedios de rnd_idx (ya que php_rand() es un alias de php_mt_rand() ).

Pero RAND_RANGE es una macro definida como #define RAND_RANGE(__n, __min, __max, __tmax) (__n) = php_mt_rand_range((__min), (__max)) por lo que el primer valor del php_rand() ya se pierde instantáneamente.

Por lo tanto, no obtendrá la lista de todos los valores de mt_range() intermedios.

Aún así, sabiendo que el algoritmo parece ser at each round, swap the current letter with a random letter before in the input string; the 1st round takes the last letter as the current one; the next round takes the letter previous current letter as the new current letter , entonces puede obtener el valor mt_rand al razonar hacia atrás.

Si ABCD es el valor de entrada y BADC es el resultado, entonces significa que los valores fueron 2;2;0 ( ABCD = > ABDC = > ABDC = > BADC ) pero aún no sabe el valor de las llamadas "perdidas" a php_mt_rand . Así que la secuencia de mt_rand fue en realidad ?;2;?;2;?;0 que coincide con la semilla 4 y 25 : si lo hace mt_srand(4); echo str_shuffle('ABCD'); , obtendrá BADC e igual si su semilla se establece en 25 . Necesitarías una cadena bastante larga de caracteres únicos para obtener una secuencia lo suficientemente larga como para que coincida solo con una semilla.

    
respondido por el Xenos 29.06.2018 - 18:09
fuente

Lea otras preguntas en las etiquetas