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