When should I use uuid.uuid1() vs. uuid.uuid4() in python?

后端 未结 6 1290
情话喂你
情话喂你 2020-12-07 07:43

I understand the differences between the two from the docs.

uuid1():
Generate a UUID from a host ID, sequence number, and the current time

<

6条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-07 08:14

    In addition to the accepted answer, there's a third option that can be useful in some cases:

    v1 with random MAC ("v1mc")

    You can make a hybrid between v1 & v4 by deliberately generating v1 UUIDs with a random broadcast MAC address (this is allowed by the v1 spec). The resulting v1 UUID is time dependant (like regular v1), but lacks all host-specific information (like v4). It's also much closer to v4 in it's collision-resistance: v1mc = 60 bits of time + 61 random bits = 121 unique bits; v4 = 122 random bits.

    First place I encountered this was Postgres' uuid_generate_v1mc() function. I've since used the following python equivalent:

    from os import urandom
    from uuid import uuid1
    _int_from_bytes = int.from_bytes  # py3 only
    
    def uuid1mc():
        # NOTE: The constant here is required by the UUIDv1 spec...
        return uuid1(_int_from_bytes(urandom(6), "big") | 0x010000000000)
    

    (note: I've got a longer + faster version that creates the UUID object directly; can post if anyone wants)


    In case of LARGE volumes of calls/second, this has the potential to exhaust system randomness. You could use the stdlib random module instead (it will probably also be faster). But BE WARNED: it only takes a few hundred UUIDs before an attacker can determine the RNG state, and thus partially predict future UUIDs.

    import random
    from uuid import uuid1
    
    def uuid1mc_insecure():
        return uuid1(random.getrandbits(48) | 0x010000000000)
    

提交回复
热议问题