Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I would like to see the code that breaks if PRNG is swapped. I mean, like is there code out there that relies on the unrandomness of current rand?


Testsets + known output, spots where the PRNG has been used as part of the seed driving cryptographic code.

The fact that a given seed makes your program deterministic is a great way to 'lock' the variation that a random generator would otherwise give you.

So, say you have a series of steps that produce a result given a random number as the seed.

You come up with a bunch of cases where the run output has been saved and checked by hand to conform, you now use that output to verify against when maintaining the software.

If you should change the behavior of the PRNG then output will change and the test will break.

A database with passwords that were 'encrypted' (I use the word loosely) using the PRNG with parts of the password as the seed. If you change the PRNG under water none of those users can log in.

There are probably lots of other examples, these are just two simple scenarios where code would break.


As far as I see these examples are all scandalous abuses of undocumented implementation details. While I can't be bothered to look up the actual documentation, I'm almost 100% sure that it's not guaranteed that PHP's rand() will always yield the same results for the same seed. But if it is, well, that would be a peculiar example of shortsighted language framework design.


> I'm almost 100% sure that it's not guaranteed that PHP's rand() will always yield the same results for the same seed.

That's the whole point of having a seed, isn't it ?

see the Periodicity entry:

http://en.wikipedia.org/wiki/Pseudorandom_number_generator

and

http://www.php.net/manual/en/function.srand.php

Does not make any mention of the behavior you cite, if you can't be bothered to look it up why bring it up in the first place ?


All I'm saying that while it is indeed true that having a seed implies a deterministic behaviour, this should be an implementation detail that should not be exposed to the the users of the interface.


Either I'm not following you, or you are not clear. Or both ;)

It is meant to work that way, for precisely the kind of reasons I outlined above.

Say you are writing a poker program. At the beginning of every game you seed the random number generator, you save the seed.

Halfway through a test you find a bug in the program.

You fix the bug (you think) and you make a test case for the fix.

You run the test case with the restored random seed to see if the bug is actually under control and does not influence any other part of the game up to there.

And so on.

That's clearly documented and very common use.

If it wouldn't be like that you'd have to play poker until the cows came home in the hope that one day that same sequence of play would occur.


What DrJokepu may have been getting at is that the implementation of rand() itself is not guaranteed. Expecting it not to change in future versions of the library is dubious.


True, but if you do not have to break stuff then don't.

After all, it was pseudo random to begin with, nobody made any claims as to how random it was, simply that it was 'periodical' and that the period was long enough that in a short lived program you would get the impression of random data.

Every programmer even halfway worth his weight in bits would know that that meant that if you needed 'high grade' random data you'd best look elsewhere, something with a longer period that downsamples to 32 bits for instance, or a hardware based random generator.

This has been true of the 'rand' function on a unix box as well, the period is (2^(sizeof(int) x 8))-1, that's just about the only guarantee you get. (hn eats asterisks)

The article linked here concentrates on the lower single bit of the output of the random generator (the rand(0,1) part of the code will generate a number between 0 and 1), but in fact completely misses the point that if you want a number that is either 0 or 1 you MASK out the lower bit instead of asking PHP to do this using the range option, which is meant to give you a number which has been 'scaled' down from the output of the PRNG in the php core. Right now you are probably sampling the lower bit of a bunch of float operations, not the best way to get one random bit.

(rand() & 1) would have done the job just fine.

So much for programmers that can manipulate bits, even after they see the implementation they still can't figure out how to do it properly. What's so hard about a one bit and ?

So, first of the article uses the PRNG in a completely nonsense way, then it is labelled as 'broken' based on a broken test and next the PHP maintainers get flak for staying backwards compatible when there was no clear need for change.

It wasn't 'broken', it could be improved a lot at the expense of backwards compatibility and so they chose the appropriate route and added a library routine for that.

I'm no big fan of PHP, but this whole thread is way over the top.

here is the same example but with the lower bit masked instead of doing a bunch of unnecessary float ops on the output of the PRNG:

http://ww.com/random.php

I would say that looks quite a bit better than the provided sample.

And I also don't get what the $x=0; is for at the end of the loop on the x-coordinate, never knew that you had to reset your loop variables.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: