2017-02-07 10 views
-1

Я читал из dev/urandom в цикле для создания случайных чисел для моделирования. Это не работает, и я в конечном итоге отслеживал проблему вниз к следующей выборке кодаполучение действительно случайных данных от dev/urandom

int myFile = open("/dev/urandom", O_RDONLY); 
begin outer loop 
for (ii = 0 ; ii<12 ; ii++) 
    { 
      read(myFile, &rand, 2) ; 
      printf("%d " , (int) rand) ; 
    } 

, получ выходных сигналов, таким как следующее. Это явно не случайное, например, число 54603 36 раз подряд, а на других прогонах количество чисел одинаковое количество раз подряд. Что здесь происходит, у меня создалось впечатление, что чтение из dev/urandom должно давать довольно случайные числа. Я делаю что-то очень плохое здесь?

Испытано на FreeBSD 10.3 и Solaris 11

14315 18369 22645 5910 55240 17092 32556 55028 34376 34902 44236 56796 
15767 54265 22372 38639 44446 25037 58094 28251 65329 48865 28057 59835 
17135 57009 5612 8627 55111 365 9988 62402 42682 57066 59920 10659 
21386 60845 9243 27377 18829 10162 64795 55836 53913 39765 51749 47917 
21522 30166 44059 30351 15622 17957 43399 26184 44558 4553 41745 54603 
2179 11970 21234 39538 45359 50854 58277 62479 4172 14207 20551 54455 
27120 22497 51021 41488 51668 50638 13894 37707 19813 40971 52191 27702 
29443 20239 59131 12186 24974 55298 56381 50092 11114 55533 11428 17223 
30520 32207 42256 31605 32485 3700 47741 25023 50723 64056 44451 25864 
30557 2136 55462 20308 35902 30238 21815 9255 48414 1956 27819 49185 
34428 59204 1955 10782 20077 59336 27867 29254 46219 28142 19108 52866 
39392 30683 40700 11760 7835 65096 22363 41318 9363 39016 34225 20539 
39956 47480 12499 49225 15360 18322 38157 61226 43010 39099 9631 49289 
40243 53645 10750 40712 32496 53093 2925 36166 60770 45263 30683 2537 
41922 56658 30762 49046 64446 11102 53481 43032 11576 31789 17015 47093 
44196 65248 30185 28250 27134 56704 42954 18203 36677 21296 22780 27224 
50771 19717 34434 16434 43648 57975 64581 51131 748 21266 26116 29653 
52032 13956 15378 8284 47951 24566 58583 61174 53515 1697 8710 46559 
54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 
54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 
54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 54603 
55683 26712 63891 36499 40089 58448 32114 14948 57516 35102 23239 45829 
62055 29107 10766 37551 30467 33145 4124 46208 60329 54800 29127 53398 
62990 41904 30506 58700 13996 24915 18279 54703 8346 29550 2794 19473 
64367 38250 23821 41639 16940 5076 26526 26796 23550 58420 10689 18614 
7471 34008 62429 27549 53162 37714 26394 37498 14193 15684 31649 31621 
7614 16389 59721 27793 58153 9808 61092 15071 42413 57890 33708 5530 
+0

Большинство «случайных» функций являются только псевдослучайными и только так хороши, как их семя. Не могли бы вы что-то придать функции, которая хотя бы немного случайна? возможно, движения курсора, или другие неуправляемые вещи? – jwsc

+1

В качестве альтернативы вы можете попробовать прочитать из '/ dev/random' вместо'/dev/urandom', первый будет блокироваться, когда энтропии недостаточно, чтобы дать вам правильную случайность, последняя не делает этого. См. Http://stackoverflow.com/a/23712611/1220089. На самом деле поцарапать все это, вам просто нужно лучшее семя по http://www.2uo.de/myths-about-urandom/ – ffledgling

+0

Что вы читали о '/ dev/urandom'? Почему вы используете ненадежный генератор, а не стандартный '/ dev'random'? Подсказка: достаточно простого поиска в Википедии. – Olaf

ответ

3

Могу ли я сделать что-то очень неправильно здесь?

Да, код использует rand без предварительной проверки возвращаемого значения read(myFile, &rand, 2).


кодекс возникли проблемы с чтением, так что проверить возвращаемое значение read().

if (read(myFile, &rand, 2) != 2) Handle_It(); 
else printf("%d " , (int) rand) ; 

Всегда ли 2? Я подозреваю, что код нетерпелив - код нужно просто подождать и попробовать еще раз, когда возвращаемое значение < 2, возможно сохранение частичный результат, когда возвращаемое значение равно 1. (Использовать массив байтов)


Еще в большем точка обзора, получение большого количества данных от "/dev/urandom" указывает, что код должен использовать новый подход для Быстрый случайных чисел. "/dev/urandom" требует времени для генерации случайных бит. Обычный подход заключается в том, чтобы выровнять качество PRNG с битами от "/dev/urandom", а затем вызвать этот PRNG.

В качестве альтернативы рассмотрите "/dev/random".


This post подробнее.

0

В конечном счете отслежено это. Кажется, повторное чтение из dev/urandom может повторять результаты. Решение похоже на то, чтобы закрыть файл снова и снова, или прочитать 1 большой кусок из dev/urandom

+0

«Кажется, повторное чтение из dev/urandom может повторять результаты». -> Когда код получил повторяющиеся результаты, каково было возвращаемое значение 'read()'? Когда возвращаемое значение равно 0, 'read (myFile, & rand, 2);' не повторял результатов, он просто не менял 'rand'. – chux

+0

@chux На самом деле, он никогда не возвращался 0. Я проверял это, в соответствии с предложением в вашем ответе. – camelccc