blob: 5ae0a3e5fa449d99bb5774f05fdde4817aea70c8 [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001r"""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
Georg Brandl1d523e12009-12-19 18:23:28 +000016 >>> uuid.uuid1() # doctest: +SKIP
Thomas Wouters0e3f5912006-08-11 14:57:12 +000017 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
Georg Brandl1d523e12009-12-19 18:23:28 +000024 >>> uuid.uuid4() # doctest: +SKIP
Thomas Wouters0e3f5912006-08-11 14:57:12 +000025 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
Guido van Rossum65b6a802007-07-09 14:03:08 +000040 b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
Thomas Wouters0e3f5912006-08-11 14:57:12 +000041
42 # make a UUID from a 16-byte string
43 >>> uuid.UUID(bytes=x.bytes)
44 UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
45"""
46
Benjamin Peterson788cb522015-10-29 20:38:04 -070047import os
Antoine Pitroua106aec2017-09-28 23:03:06 +020048import sys
Benjamin Peterson788cb522015-10-29 20:38:04 -070049
Barry Warsaw8c130d72017-02-18 15:45:49 -050050from enum import Enum
51
52
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054
Michael Felt3a1d50e2019-06-15 17:52:29 +020055# The recognized platforms - known behaviors
Miss Islington (bot)00466db2020-07-21 17:09:32 -070056if 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'
Michael Felt3a1d50e2019-06-15 17:52:29 +020063
Michael Felt0bcbfa42019-09-26 20:43:15 +010064_MAC_DELIM = b':'
65_MAC_OMITS_LEADING_ZEROES = False
66if _AIX:
67 _MAC_DELIM = b'.'
68 _MAC_OMITS_LEADING_ZEROES = True
69
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070RESERVED_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
Guido van Rossum65b6a802007-07-09 14:03:08 +000074int_ = int # The built-in int type
75bytes_ = bytes # The built-in bytes type
Guido van Rossume2a383d2007-01-15 16:59:06 +000076
Barry Warsaw8c130d72017-02-18 15:45:49 -050077
78class SafeUUID(Enum):
79 safe = 0
80 unsafe = -1
81 unknown = None
82
83
84class UUID:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000085 """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
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000089 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'.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000096
97 UUIDs have these read-only attributes:
98
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000099 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)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000104
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)
Barry Warsaw8c130d72017-02-18 15:45:49 -0500130
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).
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000134 """
135
David Hf1d8e7c2019-01-17 13:16:51 +0100136 __slots__ = ('int', 'is_safe', '__weakref__')
Tal Einat3e2b29d2018-09-06 14:34:25 +0300137
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000138 def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
Barry Warsaw8c130d72017-02-18 15:45:49 -0500139 int=None, version=None,
140 *, is_safe=SafeUUID.unknown):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000141 r"""Create a UUID from either a string of 32 hexadecimal digits,
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000142 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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000144 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)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000155 UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
156 '\x12\x34\x56\x78\x12\x34\x56\x78')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000157 UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
158 UUID(int=0x12345678123456781234567812345678)
159
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000160 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'.
Barry Warsaw8c130d72017-02-18 15:45:49 -0500164
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).
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000168 """
169
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000170 if [hex, bytes, bytes_le, fields, int].count(None) != 4:
Berker Peksagd02eb8a2016-03-20 16:49:10 +0200171 raise TypeError('one of the hex, bytes, bytes_le, fields, '
172 'or int arguments must be given')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000173 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')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000178 int = int_(hex, 16)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000179 if bytes_le is not None:
180 if len(bytes_le) != 16:
181 raise ValueError('bytes_le is not a 16-char string')
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300182 bytes = (bytes_le[4-1::-1] + bytes_le[6-1:4-1:-1] +
183 bytes_le[8-1:6-1:-1] + bytes_le[8:])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000184 if bytes is not None:
185 if len(bytes) != 16:
186 raise ValueError('bytes is not a 16-char string')
Guido van Rossum65b6a802007-07-09 14:03:08 +0000187 assert isinstance(bytes, bytes_), repr(bytes)
Philip Jenvey1221f6b2013-08-29 18:33:50 -0700188 int = int_.from_bytes(bytes, byteorder='big')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000189 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
Guido van Rossume2a383d2007-01-15 16:59:06 +0000194 if not 0 <= time_low < 1<<32:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000195 raise ValueError('field 1 out of range (need a 32-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000196 if not 0 <= time_mid < 1<<16:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000197 raise ValueError('field 2 out of range (need a 16-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000198 if not 0 <= time_hi_version < 1<<16:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000199 raise ValueError('field 3 out of range (need a 16-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000200 if not 0 <= clock_seq_hi_variant < 1<<8:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000201 raise ValueError('field 4 out of range (need an 8-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000202 if not 0 <= clock_seq_low < 1<<8:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000203 raise ValueError('field 5 out of range (need an 8-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000204 if not 0 <= node < 1<<48:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000205 raise ValueError('field 6 out of range (need a 48-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000206 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)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000209 if int is not None:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000210 if not 0 <= int < 1<<128:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000211 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.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000216 int &= ~(0xc000 << 48)
217 int |= 0x8000 << 48
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000218 # Set the version number.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000219 int &= ~(0xf000 << 64)
220 int |= version << 76
Tal Einat3e2b29d2018-09-06 14:34:25 +0300221 object.__setattr__(self, 'int', int)
222 object.__setattr__(self, 'is_safe', is_safe)
223
224 def __getstate__(self):
Tal Einat54752532018-09-10 16:11:04 +0300225 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
Tal Einat3e2b29d2018-09-06 14:34:25 +0300230 return d
231
232 def __setstate__(self, state):
Tal Einat54752532018-09-10 16:11:04 +0300233 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)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000238
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000239 def __eq__(self, other):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000240 if isinstance(other, UUID):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000241 return self.int == other.int
242 return NotImplemented
243
Guido van Rossum65b6a802007-07-09 14:03:08 +0000244 # Q. What's the value of being able to sort UUIDs?
245 # A. Use them as keys in a B-Tree or similar mapping.
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000246
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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000265 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):
Serhiy Storchaka465e60e2014-07-25 23:36:00 +0300274 return '%s(%r)' % (self.__class__.__name__, str(self))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000275
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
Guido van Rossum65b6a802007-07-09 14:03:08 +0000284 @property
285 def bytes(self):
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300286 return self.int.to_bytes(16, 'big')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287
Guido van Rossum65b6a802007-07-09 14:03:08 +0000288 @property
289 def bytes_le(self):
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000290 bytes = self.bytes
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300291 return (bytes[4-1::-1] + bytes[6-1:4-1:-1] + bytes[8-1:6-1:-1] +
Guido van Rossum65b6a802007-07-09 14:03:08 +0000292 bytes[8:])
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000293
Guido van Rossum65b6a802007-07-09 14:03:08 +0000294 @property
295 def fields(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000296 return (self.time_low, self.time_mid, self.time_hi_version,
297 self.clock_seq_hi_variant, self.clock_seq_low, self.node)
298
Guido van Rossum65b6a802007-07-09 14:03:08 +0000299 @property
300 def time_low(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000301 return self.int >> 96
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000302
Guido van Rossum65b6a802007-07-09 14:03:08 +0000303 @property
304 def time_mid(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000305 return (self.int >> 80) & 0xffff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306
Guido van Rossum65b6a802007-07-09 14:03:08 +0000307 @property
308 def time_hi_version(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000309 return (self.int >> 64) & 0xffff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000310
Guido van Rossum65b6a802007-07-09 14:03:08 +0000311 @property
312 def clock_seq_hi_variant(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000313 return (self.int >> 56) & 0xff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314
Guido van Rossum65b6a802007-07-09 14:03:08 +0000315 @property
316 def clock_seq_low(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000317 return (self.int >> 48) & 0xff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000318
Guido van Rossum65b6a802007-07-09 14:03:08 +0000319 @property
320 def time(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000321 return (((self.time_hi_version & 0x0fff) << 48) |
322 (self.time_mid << 32) | self.time_low)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000323
Guido van Rossum65b6a802007-07-09 14:03:08 +0000324 @property
325 def clock_seq(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000326 return (((self.clock_seq_hi_variant & 0x3f) << 8) |
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000327 self.clock_seq_low)
328
Guido van Rossum65b6a802007-07-09 14:03:08 +0000329 @property
330 def node(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000331 return self.int & 0xffffffffffff
332
Guido van Rossum65b6a802007-07-09 14:03:08 +0000333 @property
334 def hex(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000335 return '%032x' % self.int
336
Guido van Rossum65b6a802007-07-09 14:03:08 +0000337 @property
338 def urn(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000339 return 'urn:uuid:' + str(self)
340
Guido van Rossum65b6a802007-07-09 14:03:08 +0000341 @property
342 def variant(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000343 if not self.int & (0x8000 << 48):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000344 return RESERVED_NCS
Guido van Rossume2a383d2007-01-15 16:59:06 +0000345 elif not self.int & (0x4000 << 48):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000346 return RFC_4122
Guido van Rossume2a383d2007-01-15 16:59:06 +0000347 elif not self.int & (0x2000 << 48):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000348 return RESERVED_MICROSOFT
349 else:
350 return RESERVED_FUTURE
351
Guido van Rossum65b6a802007-07-09 14:03:08 +0000352 @property
353 def version(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000354 # The version bits are only meaningful for RFC 4122 UUIDs.
355 if self.variant == RFC_4122:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000356 return int((self.int >> 76) & 0xf)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000357
Michael Felt0bcbfa42019-09-26 20:43:15 +0100358
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))
R David Murray4be1e242013-12-17 21:13:16 -0500366 if executable is None:
367 return None
Michael Felt0bcbfa42019-09-26 20:43:15 +0100368 # 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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000384
Barry Warsaw23df2d12017-11-28 17:26:04 -0500385# 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
Michael Felt0bcbfa42019-09-26 20:43:15 +0100403
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
Barry Warsaw23df2d12017-11-28 17:26:04 -0500417 first_local_mac = None
Michael Felt0bcbfa42019-09-26 20:43:15 +0100418 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
Barry Warsaw23df2d12017-11-28 17:26:04 -0500436 return first_local_mac or None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000437
Michael Felt0bcbfa42019-09-26 20:43:15 +0100438
Victor Stinnerebf6bb92020-03-17 18:36:44 +0100439def _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
Michael Felt0bcbfa42019-09-26 20:43:15 +0100467def _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:
Victor Stinnerebf6bb92020-03-17 18:36:44 +0100486 words = line.rstrip().split()
Michael Felt0bcbfa42019-09-26 20:43:15 +0100487 try:
Michael Felt0bcbfa42019-09-26 20:43:15 +0100488 word = words[column_index]
Victor Stinnerebf6bb92020-03-17 18:36:44 +0100489 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
Michael Felt0bcbfa42019-09-26 20:43:15 +0100501
502
503# The following functions call external programs to 'get' a macaddr value to
504# be used as basis for an uuid
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000505def _ifconfig_getnode():
506 """Get the hardware address on Unix by running ifconfig."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000507 # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200508 keywords = (b'hwaddr', b'ether', b'address:', b'lladdr')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000509 for args in ('', '-a', '-av'):
Michael Felt0bcbfa42019-09-26 20:43:15 +0100510 mac = _find_mac_near_keyword('ifconfig', args, keywords, lambda i: i+1)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000511 if mac:
512 return mac
Barry Warsaw23df2d12017-11-28 17:26:04 -0500513 return None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000514
Serhiy Storchakaac4aa7b2014-11-30 20:39:04 +0200515def _ip_getnode():
516 """Get the hardware address on Unix by running ip."""
517 # This works on Linux with iproute2.
Michael Felt0bcbfa42019-09-26 20:43:15 +0100518 mac = _find_mac_near_keyword('ip', 'link', [b'link/ether'], lambda i: i+1)
Serhiy Storchakaac4aa7b2014-11-30 20:39:04 +0200519 if mac:
520 return mac
Barry Warsaw23df2d12017-11-28 17:26:04 -0500521 return None
Serhiy Storchakaac4aa7b2014-11-30 20:39:04 +0200522
Serhiy Storchakae66bb962014-11-07 12:19:40 +0200523def _arp_getnode():
524 """Get the hardware address on Unix by running arp."""
525 import os, socket
Serhiy Storchaka525d5ae2014-11-21 21:55:39 +0200526 try:
527 ip_addr = socket.gethostbyname(socket.gethostname())
528 except OSError:
529 return None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000530
531 # Try getting the MAC addr from arp based on our IP address (Solaris).
Michael Felt0bcbfa42019-09-26 20:43:15 +0100532 mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200533 if mac:
534 return mac
535
536 # This works on OpenBSD
Michael Felt0bcbfa42019-09-26 20:43:15 +0100537 mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: i+1)
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200538 if mac:
539 return mac
540
541 # This works on Linux, FreeBSD and NetBSD
Michael Felt0bcbfa42019-09-26 20:43:15 +0100542 mac = _find_mac_near_keyword('arp', '-an', [os.fsencode('(%s)' % ip_addr)],
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200543 lambda i: i+2)
Barry Warsaw23df2d12017-11-28 17:26:04 -0500544 # Return None instead of 0.
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200545 if mac:
546 return mac
Barry Warsaw23df2d12017-11-28 17:26:04 -0500547 return None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000548
Serhiy Storchakae66bb962014-11-07 12:19:40 +0200549def _lanscan_getnode():
550 """Get the hardware address on Unix by running lanscan."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000551 # This might work on HP-UX.
Michael Felt0bcbfa42019-09-26 20:43:15 +0100552 return _find_mac_near_keyword('lanscan', '-ai', [b'lan0'], lambda i: 0)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000553
Serhiy Storchakae66bb962014-11-07 12:19:40 +0200554def _netstat_getnode():
555 """Get the hardware address on Unix by running netstat."""
Michael Felt0bcbfa42019-09-26 20:43:15 +0100556 # This works on AIX and might work on Tru64 UNIX.
557 return _find_mac_under_heading('netstat', '-ian', b'Address')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000558
559def _ipconfig_getnode():
Steve Dowerd6b727e2020-05-12 23:32:32 +0100560 """[DEPRECATED] Get the hardware address on Windows."""
561 # bpo-40501: UuidCreateSequential() is now the only supported approach
562 return _windll_getnode()
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000563
564def _netbios_getnode():
Steve Dowerd6b727e2020-05-12 23:32:32 +0100565 """[DEPRECATED] Get the hardware address on Windows."""
566 # bpo-40501: UuidCreateSequential() is now the only supported approach
567 return _windll_getnode()
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000568
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000569
Antoine Pitroua106aec2017-09-28 23:03:06 +0200570# Import optional C extension at toplevel, to help disabling it when testing
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000571try:
Antoine Pitroua106aec2017-09-28 23:03:06 +0200572 import _uuid
Steve Dowerd6b727e2020-05-12 23:32:32 +0100573 _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
Antoine Pitroua106aec2017-09-28 23:03:06 +0200576except ImportError:
577 _uuid = None
Steve Dowerd6b727e2020-05-12 23:32:32 +0100578 _generate_time_safe = None
579 _UuidCreate = None
580 _has_uuid_generate_time_safe = None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000581
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000582
Antoine Pitroua106aec2017-09-28 23:03:06 +0200583def _load_system_functions():
Steve Dowerd6b727e2020-05-12 23:32:32 +0100584 """[DEPRECATED] Platform-specific functions loaded at import time"""
Antoine Pitroua106aec2017-09-28 23:03:06 +0200585
586
587def _unix_getnode():
Steve Dowerd6b727e2020-05-12 23:32:32 +0100588 """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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000592
593def _windll_getnode():
Steve Dowerd6b727e2020-05-12 23:32:32 +0100594 """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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000598
599def _random_getnode():
Barry Warsaw23df2d12017-11-28 17:26:04 -0500600 """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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000611 import random
Barry Warsaw23df2d12017-11-28 17:26:04 -0500612 return random.getrandbits(48) | (1 << 40)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000613
Antoine Pitroua106aec2017-09-28 23:03:06 +0200614
Min ho Kim39d87b52019-08-31 06:21:19 +1000615# _OS_GETTERS, when known, are targeted for a specific OS or platform.
Michael Felt3a1d50e2019-06-15 17:52:29 +0200616# 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]
Miss Islington (bot)00466db2020-07-21 17:09:32 -0700623elif sys.platform == 'darwin':
Michael Felt3a1d50e2019-06-15 17:52:29 +0200624 _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode]
Miss Islington (bot)00466db2020-07-21 17:09:32 -0700625elif sys.platform == 'win32':
Steve Dowerd6b727e2020-05-12 23:32:32 +0100626 # bpo-40201: _windll_getnode will always succeed, so these are not needed
627 _OS_GETTERS = []
Michael Felt3a1d50e2019-06-15 17:52:29 +0200628elif _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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000640_node = None
641
Shantanu8b6f6522020-02-05 12:43:09 -0800642def getnode():
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000643 """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 """
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000650 global _node
651 if _node is not None:
652 return _node
653
Michael Felt3a1d50e2019-06-15 17:52:29 +0200654 for getter in _GETTERS + [_random_getnode]:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000655 try:
656 _node = getter()
657 except:
658 continue
Bo Bayles6b273f72018-01-23 19:11:44 -0600659 if (_node is not None) and (0 <= _node < (1 << 48)):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000660 return _node
Bo Bayles6b273f72018-01-23 19:11:44 -0600661 assert False, '_random_getnode() returned invalid value: {}'.format(_node)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000662
Antoine Pitroua106aec2017-09-28 23:03:06 +0200663
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000664_last_timestamp = None
665
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000666def 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).
Antoine Pitroua106aec2017-09-28 23:03:06 +0200674 if _generate_time_safe is not None and node is clock_seq is None:
675 uuid_time, safely_generated = _generate_time_safe()
Barry Warsaw8c130d72017-02-18 15:45:49 -0500676 try:
677 is_safe = SafeUUID(safely_generated)
678 except ValueError:
679 is_safe = SafeUUID.unknown
Antoine Pitroua106aec2017-09-28 23:03:06 +0200680 return UUID(bytes=uuid_time, is_safe=is_safe)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000681
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000682 global _last_timestamp
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000683 import time
Victor Stinner62a68b72018-12-18 11:45:13 +0100684 nanoseconds = time.time_ns()
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000685 # 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.
Victor Stinner62a68b72018-12-18 11:45:13 +0100687 timestamp = nanoseconds // 100 + 0x01b21dd213814000
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000688 if _last_timestamp is not None and timestamp <= _last_timestamp:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000689 timestamp = _last_timestamp + 1
690 _last_timestamp = timestamp
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000691 if clock_seq is None:
692 import random
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300693 clock_seq = random.getrandbits(14) # instead of stable storage
Guido van Rossume2a383d2007-01-15 16:59:06 +0000694 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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000699 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."""
Guido van Rossume7ba4952007-06-06 23:52:48 +0000706 from hashlib import md5
Christian Heimes7cad53e2019-09-13 02:30:00 +0200707 digest = md5(
708 namespace.bytes + bytes(name, "utf-8"),
709 usedforsecurity=False
710 ).digest()
711 return UUID(bytes=digest[:16], version=3)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000712
713def uuid4():
714 """Generate a random UUID."""
Benjamin Peterson788cb522015-10-29 20:38:04 -0700715 return UUID(bytes=os.urandom(16), version=4)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000716
717def uuid5(namespace, name):
718 """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
Guido van Rossume7ba4952007-06-06 23:52:48 +0000719 from hashlib import sha1
Guido van Rossum65b6a802007-07-09 14:03:08 +0000720 hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()
Guido van Rossum5ed033b2007-07-09 14:29:40 +0000721 return UUID(bytes=hash[:16], version=5)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000722
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')