-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UUIDs are not actually 128-bits of randomness #1
Comments
Curiously enough, regardless of the seed, it always finds a duplicate in 1048576 generations. Since we are generating 16-bytes each time, 1048576 * 16 = 16,777,216 which is exactly equal to Since each time we are doing a modulus So, since the |
Well, well, well. Also within
Which are going to suffer from the same deficiencies... and I use them like everywhere for unit tests... Noted. Damn fine bug reporting. |
I implemented a new "randomness" API and back-end with utilities for generating all sorts of random types and bounded data sets as well as various discrete and continuous statistical distributions for said randomness... The new distributions generator back-end is backed by an LRG algorithm which looks very good and does reseed itself after every pass. When I get time, I'll add unit tests to prove its randomness and hook it up to The plan is to have a generic API for seeding and setting the random generator algorithm which is then used by the rest of the library, so you can use libc or the new LRG generator libGimbal will provide or whatever else. Newfangled randomness API: "Lehmer" LRG back-end (not yet exposed):
|
Holy shit, dude, how terrible is whatever version of libC you're testing with? I'm redoing your test setup with pitting the default libc rand() against my new lehmer LCG random generator, and I'm basically getting an infinite loop with either algorithm trying to match 4 bytes in a row, neither ever completes.
Check out how many iterations I have to run just to find a match of 3 bytes being duplicated... At least it does look as though the new generator does collide less than the C stdlib one does, and it's also faster too. |
Currently on vacation away from my computer. When I get back in a week I’ll do more testing and find out why it found a collision so soon. |
Ugh. Okay, the new generator has issues on the Dreamcast build, because it relies on |
We now have full 64-bits of floating point precision with |
Problem
In gimbal_uuid.c, UUIDs are generated with the following:
where
gblRandRange(0,255)
resolves toThe C standard library$2^{32} -1$ long period before it begins repeating for any given seed.
rand()
will typically only have aThe issue arises, because generating multiple random numbers, and concatenating them, does not increase randomness. Since a PRNG's output is determinate, for any given seed, every next value is determinate.
Also, there is no reseeding after it is initially seeded.
In the following program I wrote which basically implements the same behavior
Gives the following output
Solution
To generate proper UUIDs with all the necessary bits of randomness, implementing a 128-bit PRNG yourself will likely be the best option. An LFSR or an LCG are commonly used in PRNGs.
In addition, you could also find out a scheme for reseeding your RNG in-between number generations, that could help too.
The text was updated successfully, but these errors were encountered: