Is this secure?

Paul Rubin at nospam.invalid
Wed Feb 24 21:09:54 CET 2010

mk <mrkafk at> writes:
> def rand_str_custom(n):
>     s = os.urandom(n)
>     return ''.join([chr(ord('a') + ord(x) % 26) for x in s if ord(x) < 234])

Note that simply throws away some of the chars.  You have to replace
them, not throw them away.

> rand_str_SystemRandom_seeding
> mean 3845.15384615 std dev 46.2016419186
> l 3926 1.75 std devs away from mean
> y 3916 1.53 std devs away from mean

What do you think you're measuring here?  Yes, if you're doing 1000's of
draws from a distribution, you'd expect a few of them to be 1.75 sigma
from the mean.  Since there are 26 letters, you'd expect a multinomial
distribution which you can test for with the multinomial test or some
approximation from the article:

I wish I knew more statistics than I do, since there is probably some
more familiar statistical test (e.g. the T-test) that you can use as the
number of trials gets large, since each bin of the multinomial
distribution should eventually start to look like a normal distribution
due to the central limit theorem.  Others here know a lot more about
this stuff than I do, and can probably give better advice.

Anyway though, the output of os.urandom should be extremely hard to
distinguish from real randomness (that's the whole point of a
cryptographic PRNG).

More information about the Python-list mailing list