Узнайте, с чем был посеян генератор случайных чисел в C ++ - PullRequest
5 голосов
/ 27 августа 2009

У меня есть неуправляемое консольное приложение c ++, в котором я использую srand () и rand (). Мне это не нужно для решения конкретной проблемы, но мне было любопытно: передается ли исходное начальное число в srand () где-то в памяти, к которой я могу обратиться? Есть ли способ выяснить, что это было за семя?

Ответы [ 4 ]

7 голосов
/ 27 августа 2009

Семя не требуется хранить, только последнее возвращенное случайное число равно.

Вот пример с man-страницы:

       static unsigned long next = 1;

       /* RAND_MAX assumed to be 32767 */
       int myrand(void) {
           next = next * 1103515245 + 12345;
           return((unsigned)(next/65536) % 32768);
       }

       void mysrand(unsigned seed) {
           next = seed;
       }
3 голосов
/ 27 августа 2009

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

 v1 = ( seed * a + b ) % m
 v2 = (   v1 * a + b ) % m;
 v3 = (   v2 * a + b ) % m;
... 

Если вы знаете первое значение, вы можете вернуться назад в последовательности:

seed = (v1 - b)/a (mod m)

Вы не знаете семя однозначно, вы знаете только его mod m (что обычно хорошо, так как (0

Вы также можете взглянуть на китайскую теорему об остатках , хотя она не является точным соответствием.

0 голосов
/ 28 августа 2009

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

Самый простой способ сделать это - запустить приложение под отладчиком и установить точку останова, где вызывается srand(), а затем просто посмотреть на переданный параметр.

Далее будет разобрать приложение и выяснить обстоятельства вызова srand. Вполне возможно, что это происходит с текущим временем - тогда вы можете попробовать несколько догадок (вы можете сузить его до нескольких тысяч или около того) и посмотреть, дают ли они ту же последовательность случайных чисел, которую использует приложение. , (Конечно, это предполагает, что у вас есть какой-то способ узнать, каковы генерируемые случайные значения). Также возможно, что семя все время что-то тупое, как «0».

0 голосов
/ 27 августа 2009

Теоретически, нет - начальное значение используется для вычисления следующего случайного значения, и это значение (теоретически) используется для заполнения следующего случайного числа и так далее.

С точки зрения безопасности, возможность заглянуть в семя (будь то оригинальное или новое) является серьезной проблемой безопасности, поэтому я ожидаю, что вы не сможете изучить ее, даже если она где-то хранится.

...