Coverage for /pythoncovmergedfiles/medio/medio/usr/lib/python3.9/uuid.py: 31%
364 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
1r"""UUID objects (universally unique identifiers) according to RFC 4122.
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.
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.
11Typical usage:
13 >>> import uuid
15 # make a UUID based on the host ID and current time
16 >>> uuid.uuid1() # doctest: +SKIP
17 UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
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')
23 # make a random UUID
24 >>> uuid.uuid4() # doctest: +SKIP
25 UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
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')
31 # make a UUID from a string of hex digits (braces and hyphens ignored)
32 >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
34 # convert a UUID to a string of hex digits in standard form
35 >>> str(x)
36 '00010203-0405-0607-0809-0a0b0c0d0e0f'
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'
42 # make a UUID from a 16-byte string
43 >>> uuid.UUID(bytes=x.bytes)
44 UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
45"""
47import os
48import sys
50from enum import Enum
53__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
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'
64_MAC_DELIM = b':'
65_MAC_OMITS_LEADING_ZEROES = False
66if _AIX:
67 _MAC_DELIM = b'.'
68 _MAC_OMITS_LEADING_ZEROES = True
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']
74int_ = int # The built-in int type
75bytes_ = bytes # The built-in bytes type
78class SafeUUID(Enum):
79 safe = 0
80 unsafe = -1
81 unknown = None
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'.
97 UUIDs have these read-only attributes:
99 bytes the UUID as a 16-byte string (containing the six
100 integer fields in big-endian byte order)
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)
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:
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
116 time the 60-bit timestamp
117 clock_seq the 14-bit sequence number
119 hex the UUID as a 32-character hexadecimal string
121 int the UUID as a 128-bit integer
123 urn the UUID as a URN as specified in RFC 4122
125 variant the UUID variant (one of the constants RESERVED_NCS,
126 RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
128 version the UUID version number (1 through 5, meaningful only
129 when the variant is RFC_4122)
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 """
136 __slots__ = ('int', 'is_safe', '__weakref__')
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:
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)
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'.
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 """
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)
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
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)
239 def __eq__(self, other):
240 if isinstance(other, UUID):
241 return self.int == other.int
242 return NotImplemented
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.
247 def __lt__(self, other):
248 if isinstance(other, UUID):
249 return self.int < other.int
250 return NotImplemented
252 def __gt__(self, other):
253 if isinstance(other, UUID):
254 return self.int > other.int
255 return NotImplemented
257 def __le__(self, other):
258 if isinstance(other, UUID):
259 return self.int <= other.int
260 return NotImplemented
262 def __ge__(self, other):
263 if isinstance(other, UUID):
264 return self.int >= other.int
265 return NotImplemented
267 def __hash__(self):
268 return hash(self.int)
270 def __int__(self):
271 return self.int
273 def __repr__(self):
274 return '%s(%r)' % (self.__class__.__name__, str(self))
276 def __setattr__(self, name, value):
277 raise TypeError('UUID objects are immutable')
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:])
284 @property
285 def bytes(self):
286 return self.int.to_bytes(16, 'big')
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:])
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)
299 @property
300 def time_low(self):
301 return self.int >> 96
303 @property
304 def time_mid(self):
305 return (self.int >> 80) & 0xffff
307 @property
308 def time_hi_version(self):
309 return (self.int >> 64) & 0xffff
311 @property
312 def clock_seq_hi_variant(self):
313 return (self.int >> 56) & 0xff
315 @property
316 def clock_seq_low(self):
317 return (self.int >> 48) & 0xff
319 @property
320 def time(self):
321 return (((self.time_hi_version & 0x0fff) << 48) |
322 (self.time_mid << 32) | self.time_low)
324 @property
325 def clock_seq(self):
326 return (((self.clock_seq_hi_variant & 0x3f) << 8) |
327 self.clock_seq_low)
329 @property
330 def node(self):
331 return self.int & 0xffffffffffff
333 @property
334 def hex(self):
335 return '%032x' % self.int
337 @property
338 def urn(self):
339 return 'urn:uuid:' + str(self)
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
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)
359def _get_command_stdout(command, *args):
360 import io, os, shutil, subprocess
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
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
400def _is_universal(mac):
401 return not (mac & (1 << 41))
404def _find_mac_near_keyword(command, args, keywords, get_word_index):
405 """Searches a command's output for a MAC address near a keyword.
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
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
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
467def _find_mac_under_heading(command, args, heading):
468 """Looks for a MAC address under a heading in a command's output.
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
478 keywords = stdout.readline().rstrip().split()
479 try:
480 column_index = keywords.index(heading)
481 except ValueError:
482 return None
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
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
500 return first_local_mac
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
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
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
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
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
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
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)
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')
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()
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()
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
583def _load_system_functions():
584 """[DEPRECATED] Platform-specific functions loaded at import time"""
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
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
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)
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
640_node = None
642def getnode():
643 """Get the hardware address as a 48-bit positive integer.
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
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)
664_last_timestamp = None
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."""
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)
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)
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)
713def uuid4():
714 """Generate a random UUID."""
715 return UUID(bytes=os.urandom(16), version=4)
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)
723# The following standard UUIDs are for use with uuid3() or uuid5().
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')