-1

I was reading from dev/urandom in a loop to create random numbers for a simulation. It wasn't working, and I eventually tracked the problem down to the following code sample

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

yielding outputs such as the following. This is clearly not random, it gives the number 54603 36 times in a row for example, and on other runs gives numbers a similar number of times in a row. What is going on here, I was under the impression that reading from dev/urandom should give fairly random numbers. Am I doing something very wrong here?

Tested on FreeBSD 10.3 and 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
camelccc
  • 2,847
  • 8
  • 26
  • 52
  • most "random" functions are only pseudo-random and only as good as their seed. Could you feed something to the function which is at least a little bit random? maybe cursor movements, or other not trackable stuff? – jwsc Feb 07 '17 at 15:42
  • 1
    Alternatively, you could try reading from `/dev/random` instead of `/dev/urandom`, the former will block when there's not enough entropy to give you proper randomness, the latter does not do so. See http://stackoverflow.com/a/23712611/1220089. Actually scratch all that, you just need a better seed according to http://www.2uo.de/myths-about-urandom/ – ffledgling Feb 07 '17 at 16:11
  • What did you read about `/dev/urandom`? Why do you use an inherently unreliable generator and not the standard `/dev`random`? Hint: A simple Wikipedia search would suffice. – too honest for this site Feb 07 '17 at 16:29
  • @jwsc: That's basically what `/dev/?random` do. – too honest for this site Feb 07 '17 at 16:33
  • What did I read about urandom? That it should use a PRNG if insufficient entropy is available so that it will be at least non-blocking nearly random data. This result however is nothing like random. – camelccc Feb 07 '17 at 16:36
  • You should look into [proper C formatting](//prohackr112.tk/pcf). Or learn how to [thoroughly obfuscate your code](//prohackr112.tk/guide/coding/proper-c-obfuscation). – MD XF Feb 07 '17 at 18:09
  • @camelccc /dev/random and /dev/urandom are the same kernel device in [FreeBSD](https://en.wikipedia.org/wiki/Urandom#FreeBSD) – Ironlenny Mar 31 '19 at 21:44

2 Answers2

3

Am I doing something very wrong here?

Yes, code is using rand without first checking the return value of read(myFile, &rand, 2).


Code is having trouble with reading, so check the return value of read().

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

Is it always 2? I suspect code is impatient - code simply needs to wait and try again when the return value < 2, possible saving a partial result when the return value is 1. (Use a byte array)


Yet in the larger point-of-view, retrieving lots of data from "/dev/urandom" indicates code should use a new approach for rapid random numbers. "/dev/urandom" takes time to generate random bits. The usual approach is to seed a quality PRNG with bits from "/dev/urandom" and then call that PRNG.

Alternatively, consider "/dev/random".


This post goes into additional detail.

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Eventually tracked this down. It seems that repeated reading from dev/urandom can repeat results. The solution seems to be to either close the file reopen and read again, or to read 1 large chunk from dev/urandom

camelccc
  • 2,847
  • 8
  • 26
  • 52
  • "It seems that repeated reading from dev/urandom can repeat results. " --> When code received repeated results, what was the return value of `read()`? When the return value is 0, `read(myFile, &rand, 2);` did not repeat results, it simple never changed `rand`. – chux - Reinstate Monica Feb 08 '17 at 20:25
  • @chux Actually, it never returned 0. I did check this, per the suggestion in your answer. – camelccc Feb 08 '17 at 22:20