• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1r"""UUID objects (universally unique identifiers) according to RFC 4122.
2
3This module provides immutable UUID objects (class UUID) and the functions
4uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5
5UUIDs as specified in RFC 4122.
6
7If all you want is a unique ID, you should probably call uuid1() or uuid4().
8Note that uuid1() may compromise privacy since it creates a UUID containing
9the computer's network address.  uuid4() creates a random UUID.
10
11Typical usage:
12
13    >>> import uuid
14
15    # make a UUID based on the host ID and current time
16    >>> uuid.uuid1()    # doctest: +SKIP
17    UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
18
19    # make a UUID using an MD5 hash of a namespace UUID and a name
20    >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
21    UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
22
23    # make a random UUID
24    >>> uuid.uuid4()    # doctest: +SKIP
25    UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
26
27    # make a UUID using a SHA-1 hash of a namespace UUID and a name
28    >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
29    UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
30
31    # make a UUID from a string of hex digits (braces and hyphens ignored)
32    >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
33
34    # convert a UUID to a string of hex digits in standard form
35    >>> str(x)
36    '00010203-0405-0607-0809-0a0b0c0d0e0f'
37
38    # get the raw 16 bytes of the UUID
39    >>> x.bytes
40    b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
41
42    # make a UUID from a 16-byte string
43    >>> uuid.UUID(bytes=x.bytes)
44    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
45"""
46
47import os
48import sys
49
50from enum import Enum
51
52
53__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
54
55# The recognized platforms - known behaviors
56if sys.platform in ('win32', 'darwin'):
57    _AIX = _LINUX = False
58else:
59    import platform
60    _platform_system = platform.system()
61    _AIX     = _platform_system == 'AIX'
62    _LINUX   = _platform_system == 'Linux'
63
64_MAC_DELIM = b':'
65_MAC_OMITS_LEADING_ZEROES = False
66if _AIX:
67    _MAC_DELIM = b'.'
68    _MAC_OMITS_LEADING_ZEROES = True
69
70RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
71    'reserved for NCS compatibility', 'specified in RFC 4122',
72    'reserved for Microsoft compatibility', 'reserved for future definition']
73
74int_ = int      # The built-in int type
75bytes_ = bytes  # The built-in bytes type
76
77
78class SafeUUID(Enum):
79    safe = 0
80    unsafe = -1
81    unknown = None
82
83
84class UUID:
85    """Instances of the UUID class represent UUIDs as specified in RFC 4122.
86    UUID objects are immutable, hashable, and usable as dictionary keys.
87    Converting a UUID to a string with str() yields something in the form
88    '12345678-1234-1234-1234-123456789abc'.  The UUID constructor accepts
89    five possible forms: a similar string of hexadecimal digits, or a tuple
90    of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
91    48-bit values respectively) as an argument named 'fields', or a string
92    of 16 bytes (with all the integer fields in big-endian order) as an
93    argument named 'bytes', or a string of 16 bytes (with the first three
94    fields in little-endian order) as an argument named 'bytes_le', or a
95    single 128-bit integer as an argument named 'int'.
96
97    UUIDs have these read-only attributes:
98
99        bytes       the UUID as a 16-byte string (containing the six
100                    integer fields in big-endian byte order)
101
102        bytes_le    the UUID as a 16-byte string (with time_low, time_mid,
103                    and time_hi_version in little-endian byte order)
104
105        fields      a tuple of the six integer fields of the UUID,
106                    which are also available as six individual attributes
107                    and two derived attributes:
108
109            time_low                the first 32 bits of the UUID
110            time_mid                the next 16 bits of the UUID
111            time_hi_version         the next 16 bits of the UUID
112            clock_seq_hi_variant    the next 8 bits of the UUID
113            clock_seq_low           the next 8 bits of the UUID
114            node                    the last 48 bits of the UUID
115
116            time                    the 60-bit timestamp
117            clock_seq               the 14-bit sequence number
118
119        hex         the UUID as a 32-character hexadecimal string
120
121        int         the UUID as a 128-bit integer
122
123        urn         the UUID as a URN as specified in RFC 4122
124
125        variant     the UUID variant (one of the constants RESERVED_NCS,
126                    RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
127
128        version     the UUID version number (1 through 5, meaningful only
129                    when the variant is RFC_4122)
130
131        is_safe     An enum indicating whether the UUID has been generated in
132                    a way that is safe for multiprocessing applications, via
133                    uuid_generate_time_safe(3).
134    """
135
136    __slots__ = ('int', 'is_safe', '__weakref__')
137
138    def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
139                       int=None, version=None,
140                       *, is_safe=SafeUUID.unknown):
141        r"""Create a UUID from either a string of 32 hexadecimal digits,
142        a string of 16 bytes as the 'bytes' argument, a string of 16 bytes
143        in little-endian order as the 'bytes_le' argument, a tuple of six
144        integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
145        8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
146        the 'fields' argument, or a single 128-bit integer as the 'int'
147        argument.  When a string of hex digits is given, curly braces,
148        hyphens, and a URN prefix are all optional.  For example, these
149        expressions all yield the same UUID:
150
151        UUID('{12345678-1234-5678-1234-567812345678}')
152        UUID('12345678123456781234567812345678')
153        UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
154        UUID(bytes='\x12\x34\x56\x78'*4)
155        UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
156                      '\x12\x34\x56\x78\x12\x34\x56\x78')
157        UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
158        UUID(int=0x12345678123456781234567812345678)
159
160        Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must
161        be given.  The 'version' argument is optional; if given, the resulting
162        UUID will have its variant and version set according to RFC 4122,
163        overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.
164
165        is_safe is an enum exposed as an attribute on the instance.  It
166        indicates whether the UUID has been generated in a way that is safe
167        for multiprocessing applications, via uuid_generate_time_safe(3).
168        """
169
170        if [hex, bytes, bytes_le, fields, int].count(None) != 4:
171            raise TypeError('one of the hex, bytes, bytes_le, fields, '
172                            'or int arguments must be given')
173        if hex is not None:
174            hex = hex.replace('urn:', '').replace('uuid:', '')
175            hex = hex.strip('{}').replace('-', '')
176            if len(hex) != 32:
177                raise ValueError('badly formed hexadecimal UUID string')
178            int = int_(hex, 16)
179        if bytes_le is not None:
180            if len(bytes_le) != 16:
181                raise ValueError('bytes_le is not a 16-char string')
182            bytes = (bytes_le[4-1::-1] + bytes_le[6-1:4-1:-1] +
183                     bytes_le[8-1:6-1:-1] + bytes_le[8:])
184        if bytes is not None:
185            if len(bytes) != 16:
186                raise ValueError('bytes is not a 16-char string')
187            assert isinstance(bytes, bytes_), repr(bytes)
188            int = int_.from_bytes(bytes, byteorder='big')
189        if fields is not None:
190            if len(fields) != 6:
191                raise ValueError('fields is not a 6-tuple')
192            (time_low, time_mid, time_hi_version,
193             clock_seq_hi_variant, clock_seq_low, node) = fields
194            if not 0 <= time_low < 1<<32:
195                raise ValueError('field 1 out of range (need a 32-bit value)')
196            if not 0 <= time_mid < 1<<16:
197                raise ValueError('field 2 out of range (need a 16-bit value)')
198            if not 0 <= time_hi_version < 1<<16:
199                raise ValueError('field 3 out of range (need a 16-bit value)')
200            if not 0 <= clock_seq_hi_variant < 1<<8:
201                raise ValueError('field 4 out of range (need an 8-bit value)')
202            if not 0 <= clock_seq_low < 1<<8:
203                raise ValueError('field 5 out of range (need an 8-bit value)')
204            if not 0 <= node < 1<<48:
205                raise ValueError('field 6 out of range (need a 48-bit value)')
206            clock_seq = (clock_seq_hi_variant << 8) | clock_seq_low
207            int = ((time_low << 96) | (time_mid << 80) |
208                   (time_hi_version << 64) | (clock_seq << 48) | node)
209        if int is not None:
210            if not 0 <= int < 1<<128:
211                raise ValueError('int is out of range (need a 128-bit value)')
212        if version is not None:
213            if not 1 <= version <= 5:
214                raise ValueError('illegal version number')
215            # Set the variant to RFC 4122.
216            int &= ~(0xc000 << 48)
217            int |= 0x8000 << 48
218            # Set the version number.
219            int &= ~(0xf000 << 64)
220            int |= version << 76
221        object.__setattr__(self, 'int', int)
222        object.__setattr__(self, 'is_safe', is_safe)
223
224    def __getstate__(self):
225        d = {'int': self.int}
226        if self.is_safe != SafeUUID.unknown:
227            # is_safe is a SafeUUID instance.  Return just its value, so that
228            # it can be un-pickled in older Python versions without SafeUUID.
229            d['is_safe'] = self.is_safe.value
230        return d
231
232    def __setstate__(self, state):
233        object.__setattr__(self, 'int', state['int'])
234        # is_safe was added in 3.7; it is also omitted when it is "unknown"
235        object.__setattr__(self, 'is_safe',
236                           SafeUUID(state['is_safe'])
237                           if 'is_safe' in state else SafeUUID.unknown)
238
239    def __eq__(self, other):
240        if isinstance(other, UUID):
241            return self.int == other.int
242        return NotImplemented
243
244    # Q. What's the value of being able to sort UUIDs?
245    # A. Use them as keys in a B-Tree or similar mapping.
246
247    def __lt__(self, other):
248        if isinstance(other, UUID):
249            return self.int < other.int
250        return NotImplemented
251
252    def __gt__(self, other):
253        if isinstance(other, UUID):
254            return self.int > other.int
255        return NotImplemented
256
257    def __le__(self, other):
258        if isinstance(other, UUID):
259            return self.int <= other.int
260        return NotImplemented
261
262    def __ge__(self, other):
263        if isinstance(other, UUID):
264            return self.int >= other.int
265        return NotImplemented
266
267    def __hash__(self):
268        return hash(self.int)
269
270    def __int__(self):
271        return self.int
272
273    def __repr__(self):
274        return '%s(%r)' % (self.__class__.__name__, str(self))
275
276    def __setattr__(self, name, value):
277        raise TypeError('UUID objects are immutable')
278
279    def __str__(self):
280        hex = '%032x' % self.int
281        return '%s-%s-%s-%s-%s' % (
282            hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
283
284    @property
285    def bytes(self):
286        return self.int.to_bytes(16, 'big')
287
288    @property
289    def bytes_le(self):
290        bytes = self.bytes
291        return (bytes[4-1::-1] + bytes[6-1:4-1:-1] + bytes[8-1:6-1:-1] +
292                bytes[8:])
293
294    @property
295    def fields(self):
296        return (self.time_low, self.time_mid, self.time_hi_version,
297                self.clock_seq_hi_variant, self.clock_seq_low, self.node)
298
299    @property
300    def time_low(self):
301        return self.int >> 96
302
303    @property
304    def time_mid(self):
305        return (self.int >> 80) & 0xffff
306
307    @property
308    def time_hi_version(self):
309        return (self.int >> 64) & 0xffff
310
311    @property
312    def clock_seq_hi_variant(self):
313        return (self.int >> 56) & 0xff
314
315    @property
316    def clock_seq_low(self):
317        return (self.int >> 48) & 0xff
318
319    @property
320    def time(self):
321        return (((self.time_hi_version & 0x0fff) << 48) |
322                (self.time_mid << 32) | self.time_low)
323
324    @property
325    def clock_seq(self):
326        return (((self.clock_seq_hi_variant & 0x3f) << 8) |
327                self.clock_seq_low)
328
329    @property
330    def node(self):
331        return self.int & 0xffffffffffff
332
333    @property
334    def hex(self):
335        return '%032x' % self.int
336
337    @property
338    def urn(self):
339        return 'urn:uuid:' + str(self)
340
341    @property
342    def variant(self):
343        if not self.int & (0x8000 << 48):
344            return RESERVED_NCS
345        elif not self.int & (0x4000 << 48):
346            return RFC_4122
347        elif not self.int & (0x2000 << 48):
348            return RESERVED_MICROSOFT
349        else:
350            return RESERVED_FUTURE
351
352    @property
353    def version(self):
354        # The version bits are only meaningful for RFC 4122 UUIDs.
355        if self.variant == RFC_4122:
356            return int((self.int >> 76) & 0xf)
357
358
359def _get_command_stdout(command, *args):
360    import io, os, shutil, subprocess
361
362    try:
363        path_dirs = os.environ.get('PATH', os.defpath).split(os.pathsep)
364        path_dirs.extend(['/sbin', '/usr/sbin'])
365        executable = shutil.which(command, path=os.pathsep.join(path_dirs))
366        if executable is None:
367            return None
368        # LC_ALL=C to ensure English output, stderr=DEVNULL to prevent output
369        # on stderr (Note: we don't have an example where the words we search
370        # for are actually localized, but in theory some system could do so.)
371        env = dict(os.environ)
372        env['LC_ALL'] = 'C'
373        proc = subprocess.Popen((executable,) + args,
374                                stdout=subprocess.PIPE,
375                                stderr=subprocess.DEVNULL,
376                                env=env)
377        if not proc:
378            return None
379        stdout, stderr = proc.communicate()
380        return io.BytesIO(stdout)
381    except (OSError, subprocess.SubprocessError):
382        return None
383
384
385# For MAC (a.k.a. IEEE 802, or EUI-48) addresses, the second least significant
386# bit of the first octet signifies whether the MAC address is universally (0)
387# or locally (1) administered.  Network cards from hardware manufacturers will
388# always be universally administered to guarantee global uniqueness of the MAC
389# address, but any particular machine may have other interfaces which are
390# locally administered.  An example of the latter is the bridge interface to
391# the Touch Bar on MacBook Pros.
392#
393# This bit works out to be the 42nd bit counting from 1 being the least
394# significant, or 1<<41.  We'll prefer universally administered MAC addresses
395# over locally administered ones since the former are globally unique, but
396# we'll return the first of the latter found if that's all the machine has.
397#
398# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
399
400def _is_universal(mac):
401    return not (mac & (1 << 41))
402
403
404def _find_mac_near_keyword(command, args, keywords, get_word_index):
405    """Searches a command's output for a MAC address near a keyword.
406
407    Each line of words in the output is case-insensitively searched for
408    any of the given keywords.  Upon a match, get_word_index is invoked
409    to pick a word from the line, given the index of the match.  For
410    example, lambda i: 0 would get the first word on the line, while
411    lambda i: i - 1 would get the word preceding the keyword.
412    """
413    stdout = _get_command_stdout(command, args)
414    if stdout is None:
415        return None
416
417    first_local_mac = None
418    for line in stdout:
419        words = line.lower().rstrip().split()
420        for i in range(len(words)):
421            if words[i] in keywords:
422                try:
423                    word = words[get_word_index(i)]
424                    mac = int(word.replace(_MAC_DELIM, b''), 16)
425                except (ValueError, IndexError):
426                    # Virtual interfaces, such as those provided by
427                    # VPNs, do not have a colon-delimited MAC address
428                    # as expected, but a 16-byte HWAddr separated by
429                    # dashes. These should be ignored in favor of a
430                    # real MAC address
431                    pass
432                else:
433                    if _is_universal(mac):
434                        return mac
435                    first_local_mac = first_local_mac or mac
436    return first_local_mac or None
437
438
439def _parse_mac(word):
440    # Accept 'HH:HH:HH:HH:HH:HH' MAC address (ex: '52:54:00:9d:0e:67'),
441    # but reject IPv6 address (ex: 'fe80::5054:ff:fe9' or '123:2:3:4:5:6:7:8').
442    #
443    # Virtual interfaces, such as those provided by VPNs, do not have a
444    # colon-delimited MAC address as expected, but a 16-byte HWAddr separated
445    # by dashes. These should be ignored in favor of a real MAC address
446    parts = word.split(_MAC_DELIM)
447    if len(parts) != 6:
448        return
449    if _MAC_OMITS_LEADING_ZEROES:
450        # (Only) on AIX the macaddr value given is not prefixed by 0, e.g.
451        # en0   1500  link#2      fa.bc.de.f7.62.4 110854824     0 160133733     0     0
452        # not
453        # en0   1500  link#2      fa.bc.de.f7.62.04 110854824     0 160133733     0     0
454        if not all(1 <= len(part) <= 2 for part in parts):
455            return
456        hexstr = b''.join(part.rjust(2, b'0') for part in parts)
457    else:
458        if not all(len(part) == 2 for part in parts):
459            return
460        hexstr = b''.join(parts)
461    try:
462        return int(hexstr, 16)
463    except ValueError:
464        return
465
466
467def _find_mac_under_heading(command, args, heading):
468    """Looks for a MAC address under a heading in a command's output.
469
470    The first line of words in the output is searched for the given
471    heading. Words at the same word index as the heading in subsequent
472    lines are then examined to see if they look like MAC addresses.
473    """
474    stdout = _get_command_stdout(command, args)
475    if stdout is None:
476        return None
477
478    keywords = stdout.readline().rstrip().split()
479    try:
480        column_index = keywords.index(heading)
481    except ValueError:
482        return None
483
484    first_local_mac = None
485    for line in stdout:
486        words = line.rstrip().split()
487        try:
488            word = words[column_index]
489        except IndexError:
490            continue
491
492        mac = _parse_mac(word)
493        if mac is None:
494            continue
495        if _is_universal(mac):
496            return mac
497        if first_local_mac is None:
498            first_local_mac = mac
499
500    return first_local_mac
501
502
503# The following functions call external programs to 'get' a macaddr value to
504# be used as basis for an uuid
505def _ifconfig_getnode():
506    """Get the hardware address on Unix by running ifconfig."""
507    # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
508    keywords = (b'hwaddr', b'ether', b'address:', b'lladdr')
509    for args in ('', '-a', '-av'):
510        mac = _find_mac_near_keyword('ifconfig', args, keywords, lambda i: i+1)
511        if mac:
512            return mac
513        return None
514
515def _ip_getnode():
516    """Get the hardware address on Unix by running ip."""
517    # This works on Linux with iproute2.
518    mac = _find_mac_near_keyword('ip', 'link', [b'link/ether'], lambda i: i+1)
519    if mac:
520        return mac
521    return None
522
523def _arp_getnode():
524    """Get the hardware address on Unix by running arp."""
525    import os, socket
526    try:
527        ip_addr = socket.gethostbyname(socket.gethostname())
528    except OSError:
529        return None
530
531    # Try getting the MAC addr from arp based on our IP address (Solaris).
532    mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
533    if mac:
534        return mac
535
536    # This works on OpenBSD
537    mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: i+1)
538    if mac:
539        return mac
540
541    # This works on Linux, FreeBSD and NetBSD
542    mac = _find_mac_near_keyword('arp', '-an', [os.fsencode('(%s)' % ip_addr)],
543                    lambda i: i+2)
544    # Return None instead of 0.
545    if mac:
546        return mac
547    return None
548
549def _lanscan_getnode():
550    """Get the hardware address on Unix by running lanscan."""
551    # This might work on HP-UX.
552    return _find_mac_near_keyword('lanscan', '-ai', [b'lan0'], lambda i: 0)
553
554def _netstat_getnode():
555    """Get the hardware address on Unix by running netstat."""
556    # This works on AIX and might work on Tru64 UNIX.
557    return _find_mac_under_heading('netstat', '-ian', b'Address')
558
559def _ipconfig_getnode():
560    """[DEPRECATED] Get the hardware address on Windows."""
561    # bpo-40501: UuidCreateSequential() is now the only supported approach
562    return _windll_getnode()
563
564def _netbios_getnode():
565    """[DEPRECATED] Get the hardware address on Windows."""
566    # bpo-40501: UuidCreateSequential() is now the only supported approach
567    return _windll_getnode()
568
569
570# Import optional C extension at toplevel, to help disabling it when testing
571try:
572    import _uuid
573    _generate_time_safe = getattr(_uuid, "generate_time_safe", None)
574    _UuidCreate = getattr(_uuid, "UuidCreate", None)
575    _has_uuid_generate_time_safe = _uuid.has_uuid_generate_time_safe
576except ImportError:
577    _uuid = None
578    _generate_time_safe = None
579    _UuidCreate = None
580    _has_uuid_generate_time_safe = None
581
582
583def _load_system_functions():
584    """[DEPRECATED] Platform-specific functions loaded at import time"""
585
586
587def _unix_getnode():
588    """Get the hardware address on Unix using the _uuid extension module."""
589    if _generate_time_safe:
590        uuid_time, _ = _generate_time_safe()
591        return UUID(bytes=uuid_time).node
592
593def _windll_getnode():
594    """Get the hardware address on Windows using the _uuid extension module."""
595    if _UuidCreate:
596        uuid_bytes = _UuidCreate()
597        return UUID(bytes_le=uuid_bytes).node
598
599def _random_getnode():
600    """Get a random node ID."""
601    # RFC 4122, $4.1.6 says "For systems with no IEEE address, a randomly or
602    # pseudo-randomly generated value may be used; see Section 4.5.  The
603    # multicast bit must be set in such addresses, in order that they will
604    # never conflict with addresses obtained from network cards."
605    #
606    # The "multicast bit" of a MAC address is defined to be "the least
607    # significant bit of the first octet".  This works out to be the 41st bit
608    # counting from 1 being the least significant bit, or 1<<40.
609    #
610    # See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
611    import random
612    return random.getrandbits(48) | (1 << 40)
613
614
615# _OS_GETTERS, when known, are targeted for a specific OS or platform.
616# The order is by 'common practice' on the specified platform.
617# Note: 'posix' and 'windows' _OS_GETTERS are prefixed by a dll/dlload() method
618# which, when successful, means none of these "external" methods are called.
619# _GETTERS is (also) used by test_uuid.py to SkipUnless(), e.g.,
620#     @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, ...)
621if _LINUX:
622    _OS_GETTERS = [_ip_getnode, _ifconfig_getnode]
623elif sys.platform == 'darwin':
624    _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode]
625elif sys.platform == 'win32':
626    # bpo-40201: _windll_getnode will always succeed, so these are not needed
627    _OS_GETTERS = []
628elif _AIX:
629    _OS_GETTERS = [_netstat_getnode]
630else:
631    _OS_GETTERS = [_ifconfig_getnode, _ip_getnode, _arp_getnode,
632                   _netstat_getnode, _lanscan_getnode]
633if os.name == 'posix':
634    _GETTERS = [_unix_getnode] + _OS_GETTERS
635elif os.name == 'nt':
636    _GETTERS = [_windll_getnode] + _OS_GETTERS
637else:
638    _GETTERS = _OS_GETTERS
639
640_node = None
641
642def getnode():
643    """Get the hardware address as a 48-bit positive integer.
644
645    The first time this runs, it may launch a separate program, which could
646    be quite slow.  If all attempts to obtain the hardware address fail, we
647    choose a random 48-bit number with its eighth bit set to 1 as recommended
648    in RFC 4122.
649    """
650    global _node
651    if _node is not None:
652        return _node
653
654    for getter in _GETTERS + [_random_getnode]:
655        try:
656            _node = getter()
657        except:
658            continue
659        if (_node is not None) and (0 <= _node < (1 << 48)):
660            return _node
661    assert False, '_random_getnode() returned invalid value: {}'.format(_node)
662
663
664_last_timestamp = None
665
666def uuid1(node=None, clock_seq=None):
667    """Generate a UUID from a host ID, sequence number, and the current time.
668    If 'node' is not given, getnode() is used to obtain the hardware
669    address.  If 'clock_seq' is given, it is used as the sequence number;
670    otherwise a random 14-bit sequence number is chosen."""
671
672    # When the system provides a version-1 UUID generator, use it (but don't
673    # use UuidCreate here because its UUIDs don't conform to RFC 4122).
674    if _generate_time_safe is not None and node is clock_seq is None:
675        uuid_time, safely_generated = _generate_time_safe()
676        try:
677            is_safe = SafeUUID(safely_generated)
678        except ValueError:
679            is_safe = SafeUUID.unknown
680        return UUID(bytes=uuid_time, is_safe=is_safe)
681
682    global _last_timestamp
683    import time
684    nanoseconds = time.time_ns()
685    # 0x01b21dd213814000 is the number of 100-ns intervals between the
686    # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
687    timestamp = nanoseconds // 100 + 0x01b21dd213814000
688    if _last_timestamp is not None and timestamp <= _last_timestamp:
689        timestamp = _last_timestamp + 1
690    _last_timestamp = timestamp
691    if clock_seq is None:
692        import random
693        clock_seq = random.getrandbits(14) # instead of stable storage
694    time_low = timestamp & 0xffffffff
695    time_mid = (timestamp >> 32) & 0xffff
696    time_hi_version = (timestamp >> 48) & 0x0fff
697    clock_seq_low = clock_seq & 0xff
698    clock_seq_hi_variant = (clock_seq >> 8) & 0x3f
699    if node is None:
700        node = getnode()
701    return UUID(fields=(time_low, time_mid, time_hi_version,
702                        clock_seq_hi_variant, clock_seq_low, node), version=1)
703
704def uuid3(namespace, name):
705    """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
706    from hashlib import md5
707    digest = md5(
708        namespace.bytes + bytes(name, "utf-8"),
709        usedforsecurity=False
710    ).digest()
711    return UUID(bytes=digest[:16], version=3)
712
713def uuid4():
714    """Generate a random UUID."""
715    return UUID(bytes=os.urandom(16), version=4)
716
717def uuid5(namespace, name):
718    """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
719    from hashlib import sha1
720    hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()
721    return UUID(bytes=hash[:16], version=5)
722
723# The following standard UUIDs are for use with uuid3() or uuid5().
724
725NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
726NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
727NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
728NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')
729