msg144087 - (view) |
Author: Matt Chaput (mattchaput) |
Date: 2011-09-15 16:30 |
Currently the 'uuid' module uses os.urandom (in the absence of a system UUID generation function) to generate random UUIDs in the uuid.uudi4() function. This patch changes the implementation of uuid4() to use random.getrandbits() as the source of randomness instead, for the following reasons: * In my quick tests, using getrandbits() is much faster on Windows and Linux. Some applications do need to generate UUIDs quickly. >>> setup = "import uuid, os, random" >>> ur = "uuid.UUID(bytes=os.urandom(16), version=4)" >>> grb = "uuid.UUID(int=random.getrandbits(128), version=4)" >>> # Windows -------- >>> timeit.Timer(ur, setup).timeit() 22.861042160383903 >>> timeit.Timer(grb, setup).timeit() 3.8689128309085135 >>> # Linux -------- >>> timeit.Timer(ur, setup).timeit() 29.32686185836792 >> timeit.Timer(grb, setup).timeit() 3.7429409027099609 * The patched code is cleaner. It avoids the try...finally required by the possibly unavailable os.urandom function, and the fallback to generating random bytes. |
|
|
msg144156 - (view) |
Author: Terry J. Reedy (terry.reedy) *  |
Date: 2011-09-16 20:32 |
You could help this along by both running Lib.test.test_uuid with your patch applied and reporting that it passes. Raymond, I added you because this is about changing random functions. Side note: This code in test_uuid.test_uuid4() uuids = {} for u in [uuid.uuid4() for i in range(1000)]: uuids[u] = 1 equal(len(uuids.keys()), 1000) could be updated to use sets rather than a fake dict: uuids = set() for u in [uuid.uuid4() for i in range(1000)]: uuids.add(u) equal(len(uuids), 1000) |
|
|
msg144159 - (view) |
Author: Matt Chaput (mattchaput) |
Date: 2011-09-16 20:53 |
Passed all tests OK. |
|
|
msg157744 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) *  |
Date: 2012-04-07 17:56 |
> uuids = set() > for u in [uuid.uuid4() for i in range(1000)]: > uuids.add(u) uuids = {uuid.uuid4() for i in range(1000)} However, I'm not sure of the legitimacy of replacement suitable for cryptographic use `os.urandom` on fast pseudo-random `random.getrandbits`. Especially for applications that need to generate a lot of uuids. |
|
|
msg157755 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2012-04-07 20:06 |
> However, I'm not sure of the legitimacy of replacement suitable for > cryptographic use `os.urandom` on fast pseudo-random > `random.getrandbits`. Especially for applications that need to generate > a lot of uuids. Agreed. urandom() is supposed to incorporate "real" random, while getrandbits() uses a PRNG. Also, as the OP shows, it's easy to inject your own random source: >>> grb = "uuid.UUID(int=random.getrandbits(128), version=4)" if you really need the speed. |
|
|
msg172216 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) *  |
Date: 2012-10-06 16:28 |
I suggest to reject this proposal because of a deterioration in security. |
|
|
msg172259 - (view) |
Author: Christian Heimes (christian.heimes) *  |
Date: 2012-10-06 22:58 |
If somebody is going to implement uuid based on the random module that somebody must take care of fork. Currently the PRGN in random isn't reseeded during fork(). This would lead to 100% collisions. The tempfile module contains a workaround for the issue. I'm -1, see #15206. |
|
|
msg172260 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2012-10-06 23:00 |
Ok, let's reject the issue then. |
|
|