No, lo siento, tu generador es muy malo. Lo siembran con valores que no tienen mucha entropía (el PID se ajusta a 16 bits ...) o son altamente adivinables (la "hora actual" no es exactamente un valor secreto, todos pueden saberlo con notable exactitud). Y se sabe que el generador que se oculta bajo rand()
es rompible (depende del sistema operativo real, pero muchos sistemas usan un generador congruente lineal que puede invertirse fácilmente).
Obtendrá algo que vagamente parece aleatorio a primera vista, pero no resistirá los intentos exitosos de descifrarlo, es decir, predecir la salida futura del generador. Resistir los intentos de craqueo de los atacantes inteligentes es de lo que se trata la seguridad. Sin embargo, su generador podría ser apropiado para algunos usos no relacionados con la seguridad (aunque se sabe que rand()
también es bastante malo en estos).
Para la correcta generación de números aleatorios, necesitas:
- una semilla inicial con suficiente entropía;
- un PRNG criptográficamente seguro que expandirá esa semilla en una larga serie de bytes que serán indistinguibles de la aleatoriedad (incluso ante los ojos de un individuo inteligente y poderoso con grandes computadoras que tiene la intención de predecir el siguiente byte aleatorio).
La semilla inicial debe provenir de algunos eventos de hardware (aleatoriedad "física"), porque el software es, hasta el nivel de transistor, determinista. El sistema operativo está en una posición ideal para reunir eventos físicos (después de todo, ese es su trabajo). Por lo tanto, utilizar el sistema operativo. Esto significa:
- En sistemas similares a Unix (como Linux, FreeBSD, Solaris, MacOS X ...), use
/dev/urandom
( no /dev/random
; consulte esta respuesta para más detalles).
- En Windows (Win32), llame a
CryptGenRandom()
.
- En Java, usa
java.security.SecureRandom
.
- En .NET, use
System.Security.Cryptography.RNGCryptoServiceProvider
.