I'm way out of my pay grade, I'm trying to figure out
How much randomness does a call to random() actually provide in PostgreSQL?
Whether or not you can reasonably guess that much randomness?
What I know
I know it's not as random as people want it to be, it's just inefficient. Having concluded long ago that
md5()is a waste of time, I can just compare the sizes.
--produces "8" (in bytes) SELECT pg_column_size(random()); --produces "36" (in bytes) SELECT pg_column_size(md5(random()::text));
That's a lot of wasted space. I know we can store md5() in UUID which will take 16 bytes. But, that's still 8 bytes of waste space from our original 8 byte random().
I know PostgreSQL currently generates random numbers like this,
result = (double) random() / ((double) MAX_RANDOM_VALUE + 1); PG_RETURN_FLOAT8(result);
And, I know that
PG_RETURN_FLOAT8(result)is a macro that calls
The docs on
The characteristics of the values returned by random() depend on the system implementation. It is not suitable for cryptographic applications; see pgcrypto module for an alternative.
I believe that 8 byte float, is an Standard 754 IEEE float under the hood, also from the docs.
The data types real and double precision are inexact, variable-precision numeric types. In practice, these types are usually implementations of IEEE Standard 754 for Binary Floating-Point Arithmetic (single and double precision, respectively), to the extent that the underlying processor, operating system, and compiler support it.
I know that the full precision of IEEE 754 supports the following states that our
random()does not support.
- Negative numbers
- Negative Infinity
random value in the range
0.0 <= x < 1.0.
Not sure how accurate (I would prefer this checked with the above information), but for an 8-byte double the docs say
variable-precision, inexact 15 decimal digits precision
With all of that is anyone fluent enough in 754, and C to actually tell me how random a call to
random() really is.
Why I am asking
I made a suggestion to generate session keys not using
md5(random()::text) stored in text, but instead to use
gen_random_uuid() now I'm wondering how much it matters.