blob: 224a766ff2297fa9b80fca1a8ddd31933e1c7568 [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
Michael Felt3a1d50e2019-06-15 17:52:29 +020048import platform
Antoine Pitroua106aec2017-09-28 23:03:06 +020049import sys
Benjamin Peterson788cb522015-10-29 20:38:04 -070050
Barry Warsaw8c130d72017-02-18 15:45:49 -050051from enum import Enum
52
53
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
Thomas Wouters0e3f5912006-08-11 14:57:12 +000055
Michael Felt3a1d50e2019-06-15 17:52:29 +020056# The recognized platforms - known behaviors
57_AIX = platform.system() == 'AIX'
58_DARWIN = platform.system() == 'Darwin'
59_LINUX = platform.system() == 'Linux'
60_WINDOWS = platform.system() == 'Windows'
61
Michael Felt0bcbfa42019-09-26 20:43:15 +010062_MAC_DELIM = b':'
63_MAC_OMITS_LEADING_ZEROES = False
64if _AIX:
65 _MAC_DELIM = b'.'
66 _MAC_OMITS_LEADING_ZEROES = True
67
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
69 'reserved for NCS compatibility', 'specified in RFC 4122',
70 'reserved for Microsoft compatibility', 'reserved for future definition']
71
Guido van Rossum65b6a802007-07-09 14:03:08 +000072int_ = int # The built-in int type
73bytes_ = bytes # The built-in bytes type
Guido van Rossume2a383d2007-01-15 16:59:06 +000074
Barry Warsaw8c130d72017-02-18 15:45:49 -050075
76class SafeUUID(Enum):
77 safe = 0
78 unsafe = -1
79 unknown = None
80
81
82class UUID:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000083 """Instances of the UUID class represent UUIDs as specified in RFC 4122.
84 UUID objects are immutable, hashable, and usable as dictionary keys.
85 Converting a UUID to a string with str() yields something in the form
86 '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000087 five possible forms: a similar string of hexadecimal digits, or a tuple
88 of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
89 48-bit values respectively) as an argument named 'fields', or a string
90 of 16 bytes (with all the integer fields in big-endian order) as an
91 argument named 'bytes', or a string of 16 bytes (with the first three
92 fields in little-endian order) as an argument named 'bytes_le', or a
93 single 128-bit integer as an argument named 'int'.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000094
95 UUIDs have these read-only attributes:
96
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000097 bytes the UUID as a 16-byte string (containing the six
98 integer fields in big-endian byte order)
99
100 bytes_le the UUID as a 16-byte string (with time_low, time_mid,
101 and time_hi_version in little-endian byte order)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000102
103 fields a tuple of the six integer fields of the UUID,
104 which are also available as six individual attributes
105 and two derived attributes:
106
107 time_low the first 32 bits of the UUID
108 time_mid the next 16 bits of the UUID
109 time_hi_version the next 16 bits of the UUID
110 clock_seq_hi_variant the next 8 bits of the UUID
111 clock_seq_low the next 8 bits of the UUID
112 node the last 48 bits of the UUID
113
114 time the 60-bit timestamp
115 clock_seq the 14-bit sequence number
116
117 hex the UUID as a 32-character hexadecimal string
118
119 int the UUID as a 128-bit integer
120
121 urn the UUID as a URN as specified in RFC 4122
122
123 variant the UUID variant (one of the constants RESERVED_NCS,
124 RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
125
126 version the UUID version number (1 through 5, meaningful only
127 when the variant is RFC_4122)
Barry Warsaw8c130d72017-02-18 15:45:49 -0500128
129 is_safe An enum indicating whether the UUID has been generated in
130 a way that is safe for multiprocessing applications, via
131 uuid_generate_time_safe(3).
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000132 """
133
David Hf1d8e7c2019-01-17 13:16:51 +0100134 __slots__ = ('int', 'is_safe', '__weakref__')
Tal Einat3e2b29d2018-09-06 14:34:25 +0300135
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000136 def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
Barry Warsaw8c130d72017-02-18 15:45:49 -0500137 int=None, version=None,
138 *, is_safe=SafeUUID.unknown):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000139 r"""Create a UUID from either a string of 32 hexadecimal digits,
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000140 a string of 16 bytes as the 'bytes' argument, a string of 16 bytes
141 in little-endian order as the 'bytes_le' argument, a tuple of six
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000142 integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
143 8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
144 the 'fields' argument, or a single 128-bit integer as the 'int'
145 argument. When a string of hex digits is given, curly braces,
146 hyphens, and a URN prefix are all optional. For example, these
147 expressions all yield the same UUID:
148
149 UUID('{12345678-1234-5678-1234-567812345678}')
150 UUID('12345678123456781234567812345678')
151 UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
152 UUID(bytes='\x12\x34\x56\x78'*4)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000153 UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
154 '\x12\x34\x56\x78\x12\x34\x56\x78')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000155 UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
156 UUID(int=0x12345678123456781234567812345678)
157
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000158 Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must
159 be given. The 'version' argument is optional; if given, the resulting
160 UUID will have its variant and version set according to RFC 4122,
161 overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.
Barry Warsaw8c130d72017-02-18 15:45:49 -0500162
163 is_safe is an enum exposed as an attribute on the instance. It
164 indicates whether the UUID has been generated in a way that is safe
165 for multiprocessing applications, via uuid_generate_time_safe(3).
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000166 """
167
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000168 if [hex, bytes, bytes_le, fields, int].count(None) != 4:
Berker Peksagd02eb8a2016-03-20 16:49:10 +0200169 raise TypeError('one of the hex, bytes, bytes_le, fields, '
170 'or int arguments must be given')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000171 if hex is not None:
172 hex = hex.replace('urn:', '').replace('uuid:', '')
173 hex = hex.strip('{}').replace('-', '')
174 if len(hex) != 32:
175 raise ValueError('badly formed hexadecimal UUID string')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000176 int = int_(hex, 16)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000177 if bytes_le is not None:
178 if len(bytes_le) != 16:
179 raise ValueError('bytes_le is not a 16-char string')
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300180 bytes = (bytes_le[4-1::-1] + bytes_le[6-1:4-1:-1] +
181 bytes_le[8-1:6-1:-1] + bytes_le[8:])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000182 if bytes is not None:
183 if len(bytes) != 16:
184 raise ValueError('bytes is not a 16-char string')
Guido van Rossum65b6a802007-07-09 14:03:08 +0000185 assert isinstance(bytes, bytes_), repr(bytes)
Philip Jenvey1221f6b2013-08-29 18:33:50 -0700186 int = int_.from_bytes(bytes, byteorder='big')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000187 if fields is not None:
188 if len(fields) != 6:
189 raise ValueError('fields is not a 6-tuple')
190 (time_low, time_mid, time_hi_version,
191 clock_seq_hi_variant, clock_seq_low, node) = fields
Guido van Rossume2a383d2007-01-15 16:59:06 +0000192 if not 0 <= time_low < 1<<32:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000193 raise ValueError('field 1 out of range (need a 32-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000194 if not 0 <= time_mid < 1<<16:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000195 raise ValueError('field 2 out of range (need a 16-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000196 if not 0 <= time_hi_version < 1<<16:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000197 raise ValueError('field 3 out of range (need a 16-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000198 if not 0 <= clock_seq_hi_variant < 1<<8:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000199 raise ValueError('field 4 out of range (need an 8-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000200 if not 0 <= clock_seq_low < 1<<8:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000201 raise ValueError('field 5 out of range (need an 8-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000202 if not 0 <= node < 1<<48:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000203 raise ValueError('field 6 out of range (need a 48-bit value)')
Guido van Rossume2a383d2007-01-15 16:59:06 +0000204 clock_seq = (clock_seq_hi_variant << 8) | clock_seq_low
205 int = ((time_low << 96) | (time_mid << 80) |
206 (time_hi_version << 64) | (clock_seq << 48) | node)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000207 if int is not None:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000208 if not 0 <= int < 1<<128:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000209 raise ValueError('int is out of range (need a 128-bit value)')
210 if version is not None:
211 if not 1 <= version <= 5:
212 raise ValueError('illegal version number')
213 # Set the variant to RFC 4122.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000214 int &= ~(0xc000 << 48)
215 int |= 0x8000 << 48
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000216 # Set the version number.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000217 int &= ~(0xf000 << 64)
218 int |= version << 76
Tal Einat3e2b29d2018-09-06 14:34:25 +0300219 object.__setattr__(self, 'int', int)
220 object.__setattr__(self, 'is_safe', is_safe)
221
222 def __getstate__(self):
Tal Einat54752532018-09-10 16:11:04 +0300223 d = {'int': self.int}
224 if self.is_safe != SafeUUID.unknown:
225 # is_safe is a SafeUUID instance. Return just its value, so that
226 # it can be un-pickled in older Python versions without SafeUUID.
227 d['is_safe'] = self.is_safe.value
Tal Einat3e2b29d2018-09-06 14:34:25 +0300228 return d
229
230 def __setstate__(self, state):
Tal Einat54752532018-09-10 16:11:04 +0300231 object.__setattr__(self, 'int', state['int'])
232 # is_safe was added in 3.7; it is also omitted when it is "unknown"
233 object.__setattr__(self, 'is_safe',
234 SafeUUID(state['is_safe'])
235 if 'is_safe' in state else SafeUUID.unknown)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000236
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000237 def __eq__(self, other):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000238 if isinstance(other, UUID):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000239 return self.int == other.int
240 return NotImplemented
241
Guido van Rossum65b6a802007-07-09 14:03:08 +0000242 # Q. What's the value of being able to sort UUIDs?
243 # A. Use them as keys in a B-Tree or similar mapping.
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000244
245 def __lt__(self, other):
246 if isinstance(other, UUID):
247 return self.int < other.int
248 return NotImplemented
249
250 def __gt__(self, other):
251 if isinstance(other, UUID):
252 return self.int > other.int
253 return NotImplemented
254
255 def __le__(self, other):
256 if isinstance(other, UUID):
257 return self.int <= other.int
258 return NotImplemented
259
260 def __ge__(self, other):
261 if isinstance(other, UUID):
262 return self.int >= other.int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000263 return NotImplemented
264
265 def __hash__(self):
266 return hash(self.int)
267
268 def __int__(self):
269 return self.int
270
271 def __repr__(self):
Serhiy Storchaka465e60e2014-07-25 23:36:00 +0300272 return '%s(%r)' % (self.__class__.__name__, str(self))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000273
274 def __setattr__(self, name, value):
275 raise TypeError('UUID objects are immutable')
276
277 def __str__(self):
278 hex = '%032x' % self.int
279 return '%s-%s-%s-%s-%s' % (
280 hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
281
Guido van Rossum65b6a802007-07-09 14:03:08 +0000282 @property
283 def bytes(self):
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300284 return self.int.to_bytes(16, 'big')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000285
Guido van Rossum65b6a802007-07-09 14:03:08 +0000286 @property
287 def bytes_le(self):
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000288 bytes = self.bytes
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300289 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 +0000290 bytes[8:])
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000291
Guido van Rossum65b6a802007-07-09 14:03:08 +0000292 @property
293 def fields(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294 return (self.time_low, self.time_mid, self.time_hi_version,
295 self.clock_seq_hi_variant, self.clock_seq_low, self.node)
296
Guido van Rossum65b6a802007-07-09 14:03:08 +0000297 @property
298 def time_low(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000299 return self.int >> 96
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300
Guido van Rossum65b6a802007-07-09 14:03:08 +0000301 @property
302 def time_mid(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000303 return (self.int >> 80) & 0xffff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000304
Guido van Rossum65b6a802007-07-09 14:03:08 +0000305 @property
306 def time_hi_version(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000307 return (self.int >> 64) & 0xffff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308
Guido van Rossum65b6a802007-07-09 14:03:08 +0000309 @property
310 def clock_seq_hi_variant(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000311 return (self.int >> 56) & 0xff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000312
Guido van Rossum65b6a802007-07-09 14:03:08 +0000313 @property
314 def clock_seq_low(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000315 return (self.int >> 48) & 0xff
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000316
Guido van Rossum65b6a802007-07-09 14:03:08 +0000317 @property
318 def time(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000319 return (((self.time_hi_version & 0x0fff) << 48) |
320 (self.time_mid << 32) | self.time_low)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000321
Guido van Rossum65b6a802007-07-09 14:03:08 +0000322 @property
323 def clock_seq(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000324 return (((self.clock_seq_hi_variant & 0x3f) << 8) |
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000325 self.clock_seq_low)
326
Guido van Rossum65b6a802007-07-09 14:03:08 +0000327 @property
328 def node(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000329 return self.int & 0xffffffffffff
330
Guido van Rossum65b6a802007-07-09 14:03:08 +0000331 @property
332 def hex(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000333 return '%032x' % self.int
334
Guido van Rossum65b6a802007-07-09 14:03:08 +0000335 @property
336 def urn(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000337 return 'urn:uuid:' + str(self)
338
Guido van Rossum65b6a802007-07-09 14:03:08 +0000339 @property
340 def variant(self):
Guido van Rossume2a383d2007-01-15 16:59:06 +0000341 if not self.int & (0x8000 << 48):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000342 return RESERVED_NCS
Guido van Rossume2a383d2007-01-15 16:59:06 +0000343 elif not self.int & (0x4000 << 48):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000344 return RFC_4122
Guido van Rossume2a383d2007-01-15 16:59:06 +0000345 elif not self.int & (0x2000 << 48):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000346 return RESERVED_MICROSOFT
347 else:
348 return RESERVED_FUTURE
349
Guido van Rossum65b6a802007-07-09 14:03:08 +0000350 @property
351 def version(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000352 # The version bits are only meaningful for RFC 4122 UUIDs.
353 if self.variant == RFC_4122:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000354 return int((self.int >> 76) & 0xf)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000355
Michael Felt0bcbfa42019-09-26 20:43:15 +0100356
357def _get_command_stdout(command, *args):
358 import io, os, shutil, subprocess
359
360 try:
361 path_dirs = os.environ.get('PATH', os.defpath).split(os.pathsep)
362 path_dirs.extend(['/sbin', '/usr/sbin'])
363 executable = shutil.which(command, path=os.pathsep.join(path_dirs))
R David Murray4be1e242013-12-17 21:13:16 -0500364 if executable is None:
365 return None
Michael Felt0bcbfa42019-09-26 20:43:15 +0100366 # LC_ALL=C to ensure English output, stderr=DEVNULL to prevent output
367 # on stderr (Note: we don't have an example where the words we search
368 # for are actually localized, but in theory some system could do so.)
369 env = dict(os.environ)
370 env['LC_ALL'] = 'C'
371 proc = subprocess.Popen((executable,) + args,
372 stdout=subprocess.PIPE,
373 stderr=subprocess.DEVNULL,
374 env=env)
375 if not proc:
376 return None
377 stdout, stderr = proc.communicate()
378 return io.BytesIO(stdout)
379 except (OSError, subprocess.SubprocessError):
380 return None
381
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000382
Barry Warsaw23df2d12017-11-28 17:26:04 -0500383# For MAC (a.k.a. IEEE 802, or EUI-48) addresses, the second least significant
384# bit of the first octet signifies whether the MAC address is universally (0)
385# or locally (1) administered. Network cards from hardware manufacturers will
386# always be universally administered to guarantee global uniqueness of the MAC
387# address, but any particular machine may have other interfaces which are
388# locally administered. An example of the latter is the bridge interface to
389# the Touch Bar on MacBook Pros.
390#
391# This bit works out to be the 42nd bit counting from 1 being the least
392# significant, or 1<<41. We'll prefer universally administered MAC addresses
393# over locally administered ones since the former are globally unique, but
394# we'll return the first of the latter found if that's all the machine has.
395#
396# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
397
398def _is_universal(mac):
399 return not (mac & (1 << 41))
400
Michael Felt0bcbfa42019-09-26 20:43:15 +0100401
402def _find_mac_near_keyword(command, args, keywords, get_word_index):
403 """Searches a command's output for a MAC address near a keyword.
404
405 Each line of words in the output is case-insensitively searched for
406 any of the given keywords. Upon a match, get_word_index is invoked
407 to pick a word from the line, given the index of the match. For
408 example, lambda i: 0 would get the first word on the line, while
409 lambda i: i - 1 would get the word preceding the keyword.
410 """
411 stdout = _get_command_stdout(command, args)
412 if stdout is None:
413 return None
414
Barry Warsaw23df2d12017-11-28 17:26:04 -0500415 first_local_mac = None
Michael Felt0bcbfa42019-09-26 20:43:15 +0100416 for line in stdout:
417 words = line.lower().rstrip().split()
418 for i in range(len(words)):
419 if words[i] in keywords:
420 try:
421 word = words[get_word_index(i)]
422 mac = int(word.replace(_MAC_DELIM, b''), 16)
423 except (ValueError, IndexError):
424 # Virtual interfaces, such as those provided by
425 # VPNs, do not have a colon-delimited MAC address
426 # as expected, but a 16-byte HWAddr separated by
427 # dashes. These should be ignored in favor of a
428 # real MAC address
429 pass
430 else:
431 if _is_universal(mac):
432 return mac
433 first_local_mac = first_local_mac or mac
Barry Warsaw23df2d12017-11-28 17:26:04 -0500434 return first_local_mac or None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000435
Michael Felt0bcbfa42019-09-26 20:43:15 +0100436
437def _find_mac_under_heading(command, args, heading):
438 """Looks for a MAC address under a heading in a command's output.
439
440 The first line of words in the output is searched for the given
441 heading. Words at the same word index as the heading in subsequent
442 lines are then examined to see if they look like MAC addresses.
443 """
444 stdout = _get_command_stdout(command, args)
445 if stdout is None:
446 return None
447
448 keywords = stdout.readline().rstrip().split()
449 try:
450 column_index = keywords.index(heading)
451 except ValueError:
452 return None
453
454 first_local_mac = None
455 for line in stdout:
456 try:
457 words = line.rstrip().split()
458 word = words[column_index]
459 if len(word) == 17:
460 mac = int(word.replace(_MAC_DELIM, b''), 16)
461 elif _MAC_OMITS_LEADING_ZEROES:
462 # (Only) on AIX the macaddr value given is not prefixed by 0, e.g.
463 # en0 1500 link#2 fa.bc.de.f7.62.4 110854824 0 160133733 0 0
464 # not
465 # en0 1500 link#2 fa.bc.de.f7.62.04 110854824 0 160133733 0 0
466 parts = word.split(_MAC_DELIM)
467 if len(parts) == 6 and all(0 < len(p) <= 2 for p in parts):
468 hexstr = b''.join(p.rjust(2, b'0') for p in parts)
469 mac = int(hexstr, 16)
470 else:
471 continue
472 else:
473 continue
474 except (ValueError, IndexError):
475 # Virtual interfaces, such as those provided by
476 # VPNs, do not have a colon-delimited MAC address
477 # as expected, but a 16-byte HWAddr separated by
478 # dashes. These should be ignored in favor of a
479 # real MAC address
480 pass
481 else:
482 if _is_universal(mac):
483 return mac
484 first_local_mac = first_local_mac or mac
485 return first_local_mac or None
486
487
488# The following functions call external programs to 'get' a macaddr value to
489# be used as basis for an uuid
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000490def _ifconfig_getnode():
491 """Get the hardware address on Unix by running ifconfig."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000492 # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200493 keywords = (b'hwaddr', b'ether', b'address:', b'lladdr')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000494 for args in ('', '-a', '-av'):
Michael Felt0bcbfa42019-09-26 20:43:15 +0100495 mac = _find_mac_near_keyword('ifconfig', args, keywords, lambda i: i+1)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000496 if mac:
497 return mac
Barry Warsaw23df2d12017-11-28 17:26:04 -0500498 return None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000499
Serhiy Storchakaac4aa7b2014-11-30 20:39:04 +0200500def _ip_getnode():
501 """Get the hardware address on Unix by running ip."""
502 # This works on Linux with iproute2.
Michael Felt0bcbfa42019-09-26 20:43:15 +0100503 mac = _find_mac_near_keyword('ip', 'link', [b'link/ether'], lambda i: i+1)
Serhiy Storchakaac4aa7b2014-11-30 20:39:04 +0200504 if mac:
505 return mac
Barry Warsaw23df2d12017-11-28 17:26:04 -0500506 return None
Serhiy Storchakaac4aa7b2014-11-30 20:39:04 +0200507
Serhiy Storchakae66bb962014-11-07 12:19:40 +0200508def _arp_getnode():
509 """Get the hardware address on Unix by running arp."""
510 import os, socket
Serhiy Storchaka525d5ae2014-11-21 21:55:39 +0200511 try:
512 ip_addr = socket.gethostbyname(socket.gethostname())
513 except OSError:
514 return None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000515
516 # Try getting the MAC addr from arp based on our IP address (Solaris).
Michael Felt0bcbfa42019-09-26 20:43:15 +0100517 mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200518 if mac:
519 return mac
520
521 # This works on OpenBSD
Michael Felt0bcbfa42019-09-26 20:43:15 +0100522 mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: i+1)
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200523 if mac:
524 return mac
525
526 # This works on Linux, FreeBSD and NetBSD
Michael Felt0bcbfa42019-09-26 20:43:15 +0100527 mac = _find_mac_near_keyword('arp', '-an', [os.fsencode('(%s)' % ip_addr)],
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200528 lambda i: i+2)
Barry Warsaw23df2d12017-11-28 17:26:04 -0500529 # Return None instead of 0.
Serhiy Storchakaee1a9a22017-11-04 09:37:32 +0200530 if mac:
531 return mac
Barry Warsaw23df2d12017-11-28 17:26:04 -0500532 return None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000533
Serhiy Storchakae66bb962014-11-07 12:19:40 +0200534def _lanscan_getnode():
535 """Get the hardware address on Unix by running lanscan."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000536 # This might work on HP-UX.
Michael Felt0bcbfa42019-09-26 20:43:15 +0100537 return _find_mac_near_keyword('lanscan', '-ai', [b'lan0'], lambda i: 0)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000538
Serhiy Storchakae66bb962014-11-07 12:19:40 +0200539def _netstat_getnode():
540 """Get the hardware address on Unix by running netstat."""
Michael Felt0bcbfa42019-09-26 20:43:15 +0100541 # This works on AIX and might work on Tru64 UNIX.
542 return _find_mac_under_heading('netstat', '-ian', b'Address')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000543
544def _ipconfig_getnode():
545 """Get the hardware address on Windows by running ipconfig.exe."""
Segev Finerda6c3da2018-02-13 08:29:54 +0200546 import os, re, subprocess
Barry Warsaw23df2d12017-11-28 17:26:04 -0500547 first_local_mac = None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000548 dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
549 try:
550 import ctypes
551 buffer = ctypes.create_string_buffer(300)
552 ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)
553 dirs.insert(0, buffer.value.decode('mbcs'))
554 except:
555 pass
556 for dir in dirs:
557 try:
Segev Finerda6c3da2018-02-13 08:29:54 +0200558 proc = subprocess.Popen([os.path.join(dir, 'ipconfig'), '/all'],
559 stdout=subprocess.PIPE,
560 encoding="oem")
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200561 except OSError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000562 continue
Segev Finerda6c3da2018-02-13 08:29:54 +0200563 with proc:
564 for line in proc.stdout:
Brian Curtin69cd87b2010-11-05 14:48:35 +0000565 value = line.split(':')[-1].strip().lower()
CtrlZvic66c3422018-05-20 08:03:25 -0700566 if re.fullmatch('(?:[0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
Barry Warsaw23df2d12017-11-28 17:26:04 -0500567 mac = int(value.replace('-', ''), 16)
568 if _is_universal(mac):
569 return mac
570 first_local_mac = first_local_mac or mac
571 return first_local_mac or None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000572
573def _netbios_getnode():
574 """Get the hardware address on Windows using NetBIOS calls.
575 See http://support.microsoft.com/kb/118623 for details."""
576 import win32wnet, netbios
Barry Warsaw23df2d12017-11-28 17:26:04 -0500577 first_local_mac = None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000578 ncb = netbios.NCB()
579 ncb.Command = netbios.NCBENUM
580 ncb.Buffer = adapters = netbios.LANA_ENUM()
581 adapters._pack()
582 if win32wnet.Netbios(ncb) != 0:
Barry Warsaw23df2d12017-11-28 17:26:04 -0500583 return None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000584 adapters._unpack()
585 for i in range(adapters.length):
586 ncb.Reset()
587 ncb.Command = netbios.NCBRESET
588 ncb.Lana_num = ord(adapters.lana[i])
589 if win32wnet.Netbios(ncb) != 0:
590 continue
591 ncb.Reset()
592 ncb.Command = netbios.NCBASTAT
593 ncb.Lana_num = ord(adapters.lana[i])
594 ncb.Callname = '*'.ljust(16)
595 ncb.Buffer = status = netbios.ADAPTER_STATUS()
596 if win32wnet.Netbios(ncb) != 0:
597 continue
598 status._unpack()
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300599 bytes = status.adapter_address[:6]
600 if len(bytes) != 6:
601 continue
Barry Warsaw23df2d12017-11-28 17:26:04 -0500602 mac = int.from_bytes(bytes, 'big')
603 if _is_universal(mac):
604 return mac
605 first_local_mac = first_local_mac or mac
606 return first_local_mac or None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000607
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000608
Antoine Pitroua106aec2017-09-28 23:03:06 +0200609_generate_time_safe = _UuidCreate = None
610_has_uuid_generate_time_safe = None
611
612# Import optional C extension at toplevel, to help disabling it when testing
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000613try:
Antoine Pitroua106aec2017-09-28 23:03:06 +0200614 import _uuid
615except ImportError:
616 _uuid = None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000617
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000618
Antoine Pitroua106aec2017-09-28 23:03:06 +0200619def _load_system_functions():
620 """
621 Try to load platform-specific functions for generating uuids.
622 """
623 global _generate_time_safe, _UuidCreate, _has_uuid_generate_time_safe
Ronald Oussorenac764d32010-05-05 15:32:33 +0000624
Antoine Pitroua106aec2017-09-28 23:03:06 +0200625 if _has_uuid_generate_time_safe is not None:
626 return
627
628 _has_uuid_generate_time_safe = False
629
630 if sys.platform == "darwin" and int(os.uname().release.split('.')[0]) < 9:
631 # The uuid_generate_* functions are broken on MacOS X 10.5, as noted
632 # in issue #8621 the function generates the same sequence of values
633 # in the parent process and all children created using fork (unless
634 # those children use exec as well).
635 #
636 # Assume that the uuid_generate functions are broken from 10.5 onward,
637 # the test can be adjusted when a later version is fixed.
638 pass
639 elif _uuid is not None:
640 _generate_time_safe = _uuid.generate_time_safe
Victor Stinner4337a0d2017-10-02 07:57:59 -0700641 _has_uuid_generate_time_safe = _uuid.has_uuid_generate_time_safe
Antoine Pitroua106aec2017-09-28 23:03:06 +0200642 return
643
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000644 try:
Antoine Pitroua106aec2017-09-28 23:03:06 +0200645 # If we couldn't find an extension module, try ctypes to find
646 # system routines for UUID generation.
647 # Thanks to Thomas Heller for ctypes and for his help with its use here.
648 import ctypes
649 import ctypes.util
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000650
Antoine Pitroua106aec2017-09-28 23:03:06 +0200651 # The uuid_generate_* routines are provided by libuuid on at least
652 # Linux and FreeBSD, and provided by libc on Mac OS X.
653 _libnames = ['uuid']
654 if not sys.platform.startswith('win'):
655 _libnames.append('c')
656 for libname in _libnames:
657 try:
658 lib = ctypes.CDLL(ctypes.util.find_library(libname))
659 except Exception: # pragma: nocover
660 continue
661 # Try to find the safe variety first.
662 if hasattr(lib, 'uuid_generate_time_safe'):
663 _uuid_generate_time_safe = lib.uuid_generate_time_safe
664 # int uuid_generate_time_safe(uuid_t out);
665 def _generate_time_safe():
666 _buffer = ctypes.create_string_buffer(16)
667 res = _uuid_generate_time_safe(_buffer)
668 return bytes(_buffer.raw), res
669 _has_uuid_generate_time_safe = True
670 break
671
672 elif hasattr(lib, 'uuid_generate_time'): # pragma: nocover
673 _uuid_generate_time = lib.uuid_generate_time
674 # void uuid_generate_time(uuid_t out);
675 _uuid_generate_time.restype = None
676 def _generate_time_safe():
677 _buffer = ctypes.create_string_buffer(16)
678 _uuid_generate_time(_buffer)
679 return bytes(_buffer.raw), None
680 break
681
682 # On Windows prior to 2000, UuidCreate gives a UUID containing the
683 # hardware address. On Windows 2000 and later, UuidCreate makes a
684 # random UUID and UuidCreateSequential gives a UUID containing the
685 # hardware address. These routines are provided by the RPC runtime.
686 # NOTE: at least on Tim's WinXP Pro SP2 desktop box, while the last
687 # 6 bytes returned by UuidCreateSequential are fixed, they don't appear
688 # to bear any relationship to the MAC address of any network device
689 # on the box.
690 try:
691 lib = ctypes.windll.rpcrt4
692 except:
693 lib = None
694 _UuidCreate = getattr(lib, 'UuidCreateSequential',
695 getattr(lib, 'UuidCreate', None))
696
697 except Exception as exc:
698 import warnings
699 warnings.warn(f"Could not find fallback ctypes uuid functions: {exc}",
700 ImportWarning)
701
702
703def _unix_getnode():
704 """Get the hardware address on Unix using the _uuid extension module
705 or ctypes."""
706 _load_system_functions()
707 uuid_time, _ = _generate_time_safe()
708 return UUID(bytes=uuid_time).node
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000709
710def _windll_getnode():
711 """Get the hardware address on Windows using ctypes."""
Antoine Pitroua106aec2017-09-28 23:03:06 +0200712 import ctypes
713 _load_system_functions()
Guido van Rossum37410aa2007-08-24 04:13:42 +0000714 _buffer = ctypes.create_string_buffer(16)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000715 if _UuidCreate(_buffer) == 0:
Guido van Rossumfb56d8f2007-07-20 17:45:09 +0000716 return UUID(bytes=bytes_(_buffer.raw)).node
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000717
718def _random_getnode():
Barry Warsaw23df2d12017-11-28 17:26:04 -0500719 """Get a random node ID."""
720 # RFC 4122, $4.1.6 says "For systems with no IEEE address, a randomly or
721 # pseudo-randomly generated value may be used; see Section 4.5. The
722 # multicast bit must be set in such addresses, in order that they will
723 # never conflict with addresses obtained from network cards."
724 #
725 # The "multicast bit" of a MAC address is defined to be "the least
726 # significant bit of the first octet". This works out to be the 41st bit
727 # counting from 1 being the least significant bit, or 1<<40.
728 #
729 # See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000730 import random
Barry Warsaw23df2d12017-11-28 17:26:04 -0500731 return random.getrandbits(48) | (1 << 40)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000732
Antoine Pitroua106aec2017-09-28 23:03:06 +0200733
Min ho Kim39d87b52019-08-31 06:21:19 +1000734# _OS_GETTERS, when known, are targeted for a specific OS or platform.
Michael Felt3a1d50e2019-06-15 17:52:29 +0200735# The order is by 'common practice' on the specified platform.
736# Note: 'posix' and 'windows' _OS_GETTERS are prefixed by a dll/dlload() method
737# which, when successful, means none of these "external" methods are called.
738# _GETTERS is (also) used by test_uuid.py to SkipUnless(), e.g.,
739# @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, ...)
740if _LINUX:
741 _OS_GETTERS = [_ip_getnode, _ifconfig_getnode]
742elif _DARWIN:
743 _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode]
744elif _WINDOWS:
745 _OS_GETTERS = [_netbios_getnode, _ipconfig_getnode]
746elif _AIX:
747 _OS_GETTERS = [_netstat_getnode]
748else:
749 _OS_GETTERS = [_ifconfig_getnode, _ip_getnode, _arp_getnode,
750 _netstat_getnode, _lanscan_getnode]
751if os.name == 'posix':
752 _GETTERS = [_unix_getnode] + _OS_GETTERS
753elif os.name == 'nt':
754 _GETTERS = [_windll_getnode] + _OS_GETTERS
755else:
756 _GETTERS = _OS_GETTERS
757
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000758_node = None
759
Shantanu8b6f6522020-02-05 12:43:09 -0800760def getnode():
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000761 """Get the hardware address as a 48-bit positive integer.
762
763 The first time this runs, it may launch a separate program, which could
764 be quite slow. If all attempts to obtain the hardware address fail, we
765 choose a random 48-bit number with its eighth bit set to 1 as recommended
766 in RFC 4122.
767 """
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000768 global _node
769 if _node is not None:
770 return _node
771
Michael Felt3a1d50e2019-06-15 17:52:29 +0200772 for getter in _GETTERS + [_random_getnode]:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000773 try:
774 _node = getter()
775 except:
776 continue
Bo Bayles6b273f72018-01-23 19:11:44 -0600777 if (_node is not None) and (0 <= _node < (1 << 48)):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000778 return _node
Bo Bayles6b273f72018-01-23 19:11:44 -0600779 assert False, '_random_getnode() returned invalid value: {}'.format(_node)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000780
Antoine Pitroua106aec2017-09-28 23:03:06 +0200781
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000782_last_timestamp = None
783
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000784def uuid1(node=None, clock_seq=None):
785 """Generate a UUID from a host ID, sequence number, and the current time.
786 If 'node' is not given, getnode() is used to obtain the hardware
787 address. If 'clock_seq' is given, it is used as the sequence number;
788 otherwise a random 14-bit sequence number is chosen."""
789
790 # When the system provides a version-1 UUID generator, use it (but don't
791 # use UuidCreate here because its UUIDs don't conform to RFC 4122).
Antoine Pitroua106aec2017-09-28 23:03:06 +0200792 _load_system_functions()
793 if _generate_time_safe is not None and node is clock_seq is None:
794 uuid_time, safely_generated = _generate_time_safe()
Barry Warsaw8c130d72017-02-18 15:45:49 -0500795 try:
796 is_safe = SafeUUID(safely_generated)
797 except ValueError:
798 is_safe = SafeUUID.unknown
Antoine Pitroua106aec2017-09-28 23:03:06 +0200799 return UUID(bytes=uuid_time, is_safe=is_safe)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000800
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000801 global _last_timestamp
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000802 import time
Victor Stinner62a68b72018-12-18 11:45:13 +0100803 nanoseconds = time.time_ns()
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000804 # 0x01b21dd213814000 is the number of 100-ns intervals between the
805 # 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 +0100806 timestamp = nanoseconds // 100 + 0x01b21dd213814000
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000807 if _last_timestamp is not None and timestamp <= _last_timestamp:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000808 timestamp = _last_timestamp + 1
809 _last_timestamp = timestamp
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000810 if clock_seq is None:
811 import random
Serhiy Storchakafa9be4f2014-09-06 22:14:04 +0300812 clock_seq = random.getrandbits(14) # instead of stable storage
Guido van Rossume2a383d2007-01-15 16:59:06 +0000813 time_low = timestamp & 0xffffffff
814 time_mid = (timestamp >> 32) & 0xffff
815 time_hi_version = (timestamp >> 48) & 0x0fff
816 clock_seq_low = clock_seq & 0xff
817 clock_seq_hi_variant = (clock_seq >> 8) & 0x3f
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000818 if node is None:
819 node = getnode()
820 return UUID(fields=(time_low, time_mid, time_hi_version,
821 clock_seq_hi_variant, clock_seq_low, node), version=1)
822
823def uuid3(namespace, name):
824 """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
Guido van Rossume7ba4952007-06-06 23:52:48 +0000825 from hashlib import md5
Christian Heimes7cad53e2019-09-13 02:30:00 +0200826 digest = md5(
827 namespace.bytes + bytes(name, "utf-8"),
828 usedforsecurity=False
829 ).digest()
830 return UUID(bytes=digest[:16], version=3)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000831
832def uuid4():
833 """Generate a random UUID."""
Benjamin Peterson788cb522015-10-29 20:38:04 -0700834 return UUID(bytes=os.urandom(16), version=4)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000835
836def uuid5(namespace, name):
837 """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
Guido van Rossume7ba4952007-06-06 23:52:48 +0000838 from hashlib import sha1
Guido van Rossum65b6a802007-07-09 14:03:08 +0000839 hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()
Guido van Rossum5ed033b2007-07-09 14:29:40 +0000840 return UUID(bytes=hash[:16], version=5)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000841
842# The following standard UUIDs are for use with uuid3() or uuid5().
843
844NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
845NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
846NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
847NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')