Generalmente depende de la implementación. Para la mayoría de las partes, verás Generadores de congruencia lineal , o Linear Feedback Shift Registers .
Un problema común con estos tipos de generadores es que su período generalmente es bastante corto, y que su forma matemática implica una generación determinista. Como tal, puede (generalmente) dividirlos en unos pocos cientos de llamadas o menos. Los resultados secuenciales hacen que romper el algoritmo sea más fácil, ya que puedes hacer correlaciones más fuertes de esa manera, pero no son necesarias.
El defecto más grande con los generadores "nuevos" es que la semilla no es lo suficientemente grande. Por ejemplo, si tiene un generador con una semilla de 32 bits y conoce los primeros 20 valores del generador, es trivial a la fuerza bruta. Solo genera una secuencia para cada semilla de 0 a 2 ^ 32, y compárala. Puede emplear la optimización temprana para reducir masivamente el costo computacional de esto.
Pseudo código:
// the known values from the generator
byte[] knownValues = { 9, 55, 201, 50, 41, 111, 67, 44, 122, 66 };
for(seed = 0 to 2^32)
{
srand(seed);
bool found = true;
for(n = 0 to len(knownValues))
{
if(rand() != knownValues[n])
{
found = false;
break;
}
}
if(found == true)
{
print "Found potential seed: " + seed + "\n";
}
}
Con un RNG razonablemente rápido y un hardware decente, esto definitivamente se convierte en un ataque plausible.
Te recomiendo que leas lo siguiente para una explicación detallada: