Можно ли увеличить скорость обновления srand(time(NULL)) в C?

Я прошу посмотреть, есть ли способ увеличить скорость «обновления» функции srand(time(NULL));? Я понимаю, что srand() создает новое семя в зависимости от времени (то есть раз в секунду), но я ищу альтернативу srand(), которая может обновляться чаще, чем с интервалом в 1 секунду.

Когда я запускаю свою программу, она выдает ожидаемый результат, но начальное значение остается неизменным практически в течение секунды, поэтому, если программа запускается несколько раз в секунду, результат остается прежним.

Извините за такой простой вопрос, но я не смог найти ответ специально для C нигде в Интернете.


person KnightsThatSayNi    schedule 11.06.2015    source источник
comment
Используйте некоторое значение, полученное из gettimeofday() вместо time(), если вам нужна точность больше секунды. Это полностью ортогонально srand.   -  person user703016    schedule 11.06.2015
comment
Соответствующий выбор функции будет зависеть от операционной системы.   -  person samgak    schedule 11.06.2015
comment
Кроме того: если вас беспокоит качество ваших случайных чисел, не используйте rand.   -  person Jongware    schedule 13.06.2015
comment
Получить случайные данные с random.org (используйте аутентификацию по сертификату для предотвращения атаки MotM)   -  person M.M    schedule 13.06.2015


Ответы (4)


Вы можете попробовать получить начальное значение из другого источника. Например, в системе unix вы можете получить случайное четырехбайтное значение из /dev/random:

void randomize() {
  uint32_t seed=0;
  FILE *devrnd = fopen("/dev/random","r");
  fread(&seed, 4, 1, devrnd);
  fclose(devrnd);
  srand(seed);
}
person r3mainer    schedule 11.06.2015
comment
Кроме того, вы не хотите использовать добавление, вы хотите использовать побитовое ИЛИ. - person Richard J. Ross III; 11.06.2015
comment
Возможно, стоит отметить, что это зависит от какой-то UNIX-подобной ОС. - person Vality; 11.06.2015

srand(time(NULL)); это не функция, это скорее две функции: time() которая возвращает текущее время в секундах с начала эпохи; и srand(), который инициализирует начальное число генератора случайных чисел. Вы инициализируете начальное число генератора случайных чисел текущим временем в секундах, что вполне разумно.

Однако у вас есть несколько неправильных представлений: на самом деле вам нужно запускать srand только один раз или максимум раз в несколько минут, после чего rand() продолжит генерировать больше случайных чисел самостоятельно, srand() просто установить начальное семя для ранда, чтобы начать с .

Во-вторых, если вы действительно хотите это сделать, хотя я не понимаю, зачем вам это нужно, вы можете использовать функцию, которая возвращает время с более высокой точностью. Я бы предложил gettimeofday() для этой цели.

person Vality    schedule 11.06.2015
comment
so if the program is run multiple times a second --- противоречит вашему второму абзацу. Я считаю, что OP не вызывает srand() несколько раз в самом коде, программа запускается несколько раз. - person Sourav Ghosh; 11.06.2015
comment
@SouravGhosh Я говорю, что это неправильный подход, пользователь должен дольше сохранять программу при каждом запуске и просто запускать rand(), чтобы получить больше случайных чисел. Позвольте мне сделать это яснее - person Vality; 11.06.2015
comment
Ну, я не сказал, что вы не правы, просто сказал, что не предлагайте такие изменения, как the user should be persisting the program each run for longer. Это действительно зависит от характера программы, не так ли? - person Sourav Ghosh; 11.06.2015
comment
@SouravGhosh Это правда, однако на самом деле rand() не следует использовать ни для чего, кроме игрушечных программ. Я предполагаю, что пользователь просто пытается изучить некоторые основы C и несколько гибко подходит к тому, как работает программа. - person Vality; 11.06.2015
comment
хм.. Я думал, что rand() надежен при правильном использовании. Мне это интересно. Можете ли вы указать мне какую-нибудь ссылку, где я могу прочитать о недостатках использования rand() в реальных программах? - person Sourav Ghosh; 11.06.2015
comment
@SouravGhosh Существует множество источников, но вот довольно хорошее видео по теме channel9.msdn.com/Events/GoingNative/2013/ Подводя итог, можно сказать, что он не является криптозащищенным (что может подойти вам), но, что более важно, он не имеет определенного диапазона, кроме гарантированного не будет возвращать число больше, чем RAND_MAX (которое равно как минимум 32767), он не дает никаких гарантий относительно единообразия, поэтому реализация может иметь крайне неравномерное распределение. продолжение --› - person Vality; 11.06.2015
comment
Таким образом, по сути, нет безопасного использования ранда, вы не можете взять число как есть, поскольку нет гарантий того, каким будет диапазон, и вы не можете по модулю уменьшить его до известного диапазона, так как результат будет неоднородным, сверху что сама реализация может быть резко неоднородной. - person Vality; 11.06.2015
comment
Спасибо за информацию. Очень полезно. Однако упомянутого вами смещения по модулю можно избежать, (повторно) установив RAND_MAX, не так ли? - person Sourav Ghosh; 11.06.2015
comment
Давайте продолжим обсуждение в чате. - person Vality; 11.06.2015

В Windows вы можете использовать GetTickCount() вместо time(). Меняется с интервалом в 50 мс (если не ошибаюсь).

person i486    schedule 11.06.2015

У меня была та же проблема, я нашел простое решение с помощью часов с высоким разрешением.

#include <chrono>
#include <random>

int main() {
    long long t1 = std::chrono::high_resolution_clock::now().time_since_epoch().count();
    std::srand((unsigned int)t1);
}
person Alex Li    schedule 04.01.2021