Лучший ответ должен использовать материал случайного числа Повышения. Или если у Вас есть доступ к C++ 11, используют <random>
заголовок.
, Но если мы говорим [приблизительно 113] и srand()
, лучший способ состоит в том, чтобы только использовать time()
:
int main()
{
srand(time(NULL));
...
}
убедиться сделать это в начале Вашей программы, и не каждый раз Вы звоните rand()
!
Каждый раз, когда Вы запускаете, время () возвратит уникальное значение (если Вы не запустите приложение многократно в секунду). В системах на 32 бита это будет только повторяться каждые 60 лет или около этого.
я знаю, что Вы не думаете, что время достаточно уникально, но я нахожу, что это трудно верит. Но я, как было известно, был неправ.
при запуске большого количества копий приложения одновременно Вы могли бы использовать таймер с более прекрасным разрешением. Но тогда Вы рискуете более коротким периодом времени перед повторениями значения.
хорошо, поэтому если Вы действительно думаете, что запускаете несколько приложений в секунду.
Тогда используют более прекрасную мелкую частицу на таймере.
int main()
{
struct timeval time;
gettimeofday(&time,NULL);
// microsecond has 1 000 000
// Assuming you did not need quite that accuracy
// Also do not assume the system clock has that accuracy.
srand((time.tv_sec * 1000) + (time.tv_usec / 1000));
// The trouble here is that the seed will repeat every
// 24 days or so.
// If you use 100 (rather than 1000) the seed repeats every 248 days.
// Do not make the MISTAKE of using just the tv_usec
// This will mean your seed repeats every second.
}
#include <stdio.h>
#include <sys/time.h>
main()
{
struct timeval tv;
gettimeofday(&tv,NULL);
printf("%d\n", tv.tv_usec);
return 0;
}
ТВ tv_usec находится в микросекундах. Это должно быть приемлемым семенем.
Реальный вопрос, который необходимо задать сами, - то, в каком качестве случайности Вы нуждаетесь.
libc случайный LCG
, качество случайности будет низким, независимо от того, что введено, Вы предоставляете srand.
, Если просто необходимо удостовериться, что различные экземпляры будут иметь различные инициализации, можно смешать идентификатор процесса (getpid), идентификатор потока и таймер. Смешайте результаты с xor. Энтропия должна быть достаточной для большинства приложений.
Пример:
struct timeb tp;
ftime(&tp);
srand(static_cast<unsigned int>(getpid()) ^
static_cast<unsigned int>(pthread_self()) ^
static_cast<unsigned int >(tp.millitm));
По лучшему случайному качеству, используйте/dev/urandom. Можно сделать вышеупомянутый код портативным в использовании повышения:: поток и повышение:: date_time.
Лучший способ состоит в том, чтобы использовать другой генератор псевдослучайного числа. Вихрь Мерсенна (и Wichmann-выступ) является моей рекомендацией.
На окнах:
srand(GetTickCount());
обеспечивает лучшее семя, чем time()
начиная с в миллисекундах.
при необходимости в лучшем генераторе случайных чисел не используйте libc рэнд. Вместо этого просто используйте что-то как /dev/random
или /dev/urandom
непосредственно (чтение в int
непосредственно от него или что-то как этот).
единственная реальная выгода libc рэнда - это, учитывая семя, это предсказуемо, который помогает с отладкой.
Это - то, что я использовал для маленьких программ командной строки, которые могут запускаться часто (многократно в секунду):
unsigned long seed = mix(clock(), time(NULL), getpid());
, Где соединение:
// http://www.concentric.net/~Ttwang/tech/inthash.htm
unsigned long mix(unsigned long a, unsigned long b, unsigned long c)
{
a=a-b; a=a-c; a=a^(c >> 13);
b=b-c; b=b-a; b=b^(a << 8);
c=c-a; c=c-b; c=c^(b >> 13);
a=a-b; a=a-c; a=a^(c >> 12);
b=b-c; b=b-a; b=b^(a << 16);
c=c-a; c=c-b; c=c^(b >> 5);
a=a-b; a=a-c; a=a^(c >> 3);
b=b-c; b=b-a; b=b^(a << 10);
c=c-a; c=c-b; c=c^(b >> 15);
return c;
}
я предлагаю, чтобы Вы видели unix_random.c файл в коде Mozilla. (угадайте, что это - mozilla/security/freebl/...), это должно быть в freebl библиотеке.
там это использует информацию о системном вызове (как pwd, netstat....) для генерации шума для случайного числа; это записано для поддержки большинства платформ (который может получить меня призовой балл: D).