[C++] Maneira correta de utilizar srand()

Olá,

Sempre utilizei a função srand utilizando time(0) ou time (NULL) como parâmetro. Quando precisei criar mais de um processo no mesmo segundo, os números gerados pela função rand() são os mesmo quando comparados com os gerados pelos outros processos. Até aí tudo bem, o time vai ter o mesmo valor para todos os processos.

Qual a maneira adequada de inicializar srand()?

Encontrei o código abaixo na internet: (Infelizmente não achei muito legal)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

int main()
{
  struct timeval tv; // C requires "struct timval" instead of just "timeval"
  gettimeofday(&tv, 0);

  // use BOTH microsecond precision AND pid as seed
  long int n = tv.tv_usec * getpid(); 
  srand(n);

  printf("process %d with srand(%d) gives rand() = %d\n", getpid(), n, rand());
  printf("process %d with srand(%d) gives rand() = %d\n", getpid(), n, rand());
  printf("process %d with srand(%d) gives rand() = %d\n", getpid(), n, rand());
  printf("process %d with srand(%d) gives rand() = %d\n", getpid(), n, rand());
  printf("process %d with srand(%d) gives rand() = %d\n", getpid(), n, rand());
}

Se você quer ser realmente chato em termos de gerar números aleatórios, pode usar o OpenSSL, que faz as seguintes coisas:

  • Chama o gerador de números aleatórios do sistema operacional, caso disponível (/dev/random no Linux, CryptGenRandom no Windows);
  • Usa um monte de outras coisas (como no Windows a listagem dos PIDs e outras coisas mais estranhas).

OpenSSL RAND

O problema de você usar o tempo, é óbvio, é que mesmo tv.tv_usec não é muito legal (na verdade, muitos sistemas operacionais não conseguem garantir precisão melhor que 10 milissegundos). Mas pode até ser tolerável, para efeitos de simulação; não é tolerável para efeitos criptográficos.