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