(root)/
Python-3.11.7/
Lib/
uuid.py
       1  r"""UUID objects (universally unique identifiers) according to RFC 4122.
       2  
       3  This module provides immutable UUID objects (class UUID) and the functions
       4  uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5
       5  UUIDs as specified in RFC 4122.
       6  
       7  If all you want is a unique ID, you should probably call uuid1() or uuid4().
       8  Note that uuid1() may compromise privacy since it creates a UUID containing
       9  the computer's network address.  uuid4() creates a random UUID.
      10  
      11  Typical 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  
      47  import os
      48  import sys
      49  
      50  from enum import Enum, _simple_enum
      51  
      52  
      53  __author__ = 'Ka-Ping Yee <ping@zesty.ca>'
      54  
      55  # The recognized platforms - known behaviors
      56  if sys.platform in ('win32', 'darwin'):
      57      _AIX = _LINUX = False
      58  else:
      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
      66  if _AIX:
      67      _MAC_DELIM = b'.'
      68      _MAC_OMITS_LEADING_ZEROES = True
      69  
      70  RESERVED_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  
      74  int_ = int      # The built-in int type
      75  bytes_ = bytes  # The built-in bytes type
      76  
      77  
      78  @_simple_enum(Enum)
      79  class ESC[4;38;5;81mSafeUUID:
      80      safe = 0
      81      unsafe = -1
      82      unknown = None
      83  
      84  
      85  class ESC[4;38;5;81mUUID:
      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  
     360  def _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  
     406  def _is_universal(mac):
     407      return not (mac & (1 << 41))
     408  
     409  
     410  def _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  
     445  def _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  
     473  def _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
     511  def _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  
     521  def _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  
     529  def _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  
     557  def _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  
     562  def _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  
     567  def _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  
     572  def _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
     579  try:
     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
     584  except ImportError:
     585      _uuid = None
     586      _generate_time_safe = None
     587      _UuidCreate = None
     588      _has_uuid_generate_time_safe = None
     589  
     590  
     591  def _load_system_functions():
     592      """[DEPRECATED] Platform-specific functions loaded at import time"""
     593  
     594  
     595  def _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  
     601  def _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  
     607  def _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, ...)
     629  if _LINUX:
     630      _OS_GETTERS = [_ip_getnode, _ifconfig_getnode]
     631  elif sys.platform == 'darwin':
     632      _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode]
     633  elif sys.platform == 'win32':
     634      # bpo-40201: _windll_getnode will always succeed, so these are not needed
     635      _OS_GETTERS = []
     636  elif _AIX:
     637      _OS_GETTERS = [_netstat_getnode]
     638  else:
     639      _OS_GETTERS = [_ifconfig_getnode, _ip_getnode, _arp_getnode,
     640                     _netstat_getnode, _lanscan_getnode]
     641  if os.name == 'posix':
     642      _GETTERS = [_unix_getnode] + _OS_GETTERS
     643  elif os.name == 'nt':
     644      _GETTERS = [_windll_getnode] + _OS_GETTERS
     645  else:
     646      _GETTERS = _OS_GETTERS
     647  
     648  _node = None
     649  
     650  def 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  
     674  def 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  
     712  def 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  
     721  def uuid4():
     722      """Generate a random UUID."""
     723      return UUID(bytes=os.urandom(16), version=4)
     724  
     725  def 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  
     733  NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
     734  NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
     735  NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
     736  NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')