How to generate a random UUID which is reproducible (with a seed) in Python

前端 未结 6 1386
暗喜
暗喜 2020-12-15 14:57

The uuid4() function of Python\'s module uuid generates a random UUID, and seems to generate a different one every time:

In [1]: import uuid

In          


        
相关标签:
6条回答
  • 2020-12-15 15:33

    Since the straight-forward solution hasn't been posted yet to generate consistent version 4 UUIDs:

    import random
    import uuid
    
    rnd = random.Random()
    rnd.seed(123)
    
    uuid = uuid.UUID(int=rnd.getrandbits(128), version=4)
    
    

    where you can see then:

    >>> uuid.version
    4
    

    This doesn't just "mock" the version information. It creates a proper UUIDv4:

    The version argument is optional; if given, the resulting UUID will have its variant and version number set according to RFC 4122, overriding bits in the given hex, bytes, bytes_le, fields, or int.

    Python 3.8 docs

    0 讨论(0)
  • 2020-12-15 15:36

    Based on alex's solution, the following would provide a proper UUID4:

    random.seed(123210912)
    a = "%32x" % random.getrandbits(128)
    rd = a[:12] + '4' + a[13:16] + 'a' + a[17:]
    uuid4 = uuid.UUID(rd)
    
    0 讨论(0)
  • 2020-12-15 15:38

    Gonna add this here if anyone needs to monkey patch in a seeded UUID. My code uses uuid.uuid4() but for testing I wanted consistent UUIDs. The following code is how I did that:

    import uuid
    import random
    
    # -------------------------------------------
    # Remove this block to generate different
    # UUIDs everytime you run this code.
    # This block should be right below the uuid
    # import.
    rd = random.Random()
    rd.seed(0)
    uuid.uuid4 = lambda: uuid.UUID(int=rd.getrandbits(128))
    # -------------------------------------------
    
    # Then normal code:
    
    print(uuid.uuid4().hex)
    print(uuid.uuid4().hex)
    print(uuid.uuid4().hex)
    print(uuid.uuid4().hex)
    
    0 讨论(0)
  • 2020-12-15 15:44

    This is based on a solution used here:

    import hashlib
    import uuid
    
    m = hashlib.md5()
    m.update(seed.encode('utf-8'))
    new_uuid = uuid.UUID(m.hexdigest())
    
    0 讨论(0)
  • 2020-12-15 15:51

    Faker makes this easy

    >>> from faker import Faker
    >>> f1 = Faker()
    >>> f1.seed(4321)
    >>> print(f1.uuid4())
    cc733c92-6853-15f6-0e49-bec741188ebb
    >>> print(f1.uuid4())
    a41f020c-2d4d-333f-f1d3-979f1043fae0
    >>> f1.seed(4321)
    >>> print(f1.uuid4())
    cc733c92-6853-15f6-0e49-bec741188ebb
    
    0 讨论(0)
  • 2020-12-15 16:00

    Almost there:

    uuid.UUID(int=rd.getrandbits(128))
    

    This was determined with the help of help:

    >>> help(uuid.UUID.__init__)
    Help on method __init__ in module uuid:
    
    __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, int=None, version=None) unbound uuid.UUID method
        Create a UUID from either a string of 32 hexadecimal digits,
        a string of 16 bytes as the 'bytes' argument, a string of 16 bytes
        in little-endian order as the 'bytes_le' argument, a tuple of six
        integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
        8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
        the 'fields' argument, or a single 128-bit integer as the 'int'
        argument.  When a string of hex digits is given, curly braces,
        hyphens, and a URN prefix are all optional.  For example, these
        expressions all yield the same UUID:
    
        UUID('{12345678-1234-5678-1234-567812345678}')
        UUID('12345678123456781234567812345678')
        UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
        UUID(bytes='\x12\x34\x56\x78'*4)
        UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
                      '\x12\x34\x56\x78\x12\x34\x56\x78')
        UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
        UUID(int=0x12345678123456781234567812345678)
    
        Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must
        be given.  The 'version' argument is optional; if given, the resulting
        UUID will have its variant and version set according to RFC 4122,
        overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.
    
    0 讨论(0)
提交回复
热议问题