cpython: Lib/uuid.py annotate (original) (raw)

39442

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

65108

eb7d69d89650Merged revisions 76884-76885,76887,76889-76890,76895 via svnmerge from

Georg Brandl georg@python.org

diff changeset

16 >>> uuid.uuid1() # doctest: +SKIP

39442

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

65108

eb7d69d89650Merged revisions 76884-76885,76887,76889-76890,76895 via svnmerge from

Georg Brandl georg@python.org

diff changeset

24 >>> uuid.uuid4() # doctest: +SKIP

39442

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

42164

40 b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

39442

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

98890

70be1f9c9255always use os.urandom for the uuid4 algorithm (closes #25515)

Benjamin Peterson benjamin@python.org

diff changeset

47 import os

70be1f9c9255always use os.urandom for the uuid4 algorithm (closes #25515)

Benjamin Peterson benjamin@python.org

diff changeset

48

39442

49 __author__ = 'Ka-Ping Yee ping@zesty.ca'

50

51 RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [

52 'reserved for NCS compatibility', 'specified in RFC 4122',

53 'reserved for Microsoft compatibility', 'reserved for future definition']

54

42164

55 int_ = int # The built-in int type

56 bytes_ = bytes # The built-in bytes type

40644

57

39442

58 class UUID(object):

59 """Instances of the UUID class represent UUIDs as specified in RFC 4122.

60 UUID objects are immutable, hashable, and usable as dictionary keys.

61 Converting a UUID to a string with str() yields something in the form

62 '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

63 five possible forms: a similar string of hexadecimal digits, or a tuple

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

64 of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

65 48-bit values respectively) as an argument named 'fields', or a string

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

66 of 16 bytes (with all the integer fields in big-endian order) as an

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

67 argument named 'bytes', or a string of 16 bytes (with the first three

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

68 fields in little-endian order) as an argument named 'bytes_le', or a

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

69 single 128-bit integer as an argument named 'int'.

39442

70

71 UUIDs have these read-only attributes:

72

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

73 bytes the UUID as a 16-byte string (containing the six

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

74 integer fields in big-endian byte order)

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

75

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

76 bytes_le the UUID as a 16-byte string (with time_low, time_mid,

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

77 and time_hi_version in little-endian byte order)

39442

78

79 fields a tuple of the six integer fields of the UUID,

80 which are also available as six individual attributes

81 and two derived attributes:

82

83 time_low the first 32 bits of the UUID

84 time_mid the next 16 bits of the UUID

85 time_hi_version the next 16 bits of the UUID

86 clock_seq_hi_variant the next 8 bits of the UUID

87 clock_seq_low the next 8 bits of the UUID

88 node the last 48 bits of the UUID

89

90 time the 60-bit timestamp

91 clock_seq the 14-bit sequence number

92

93 hex the UUID as a 32-character hexadecimal string

94

95 int the UUID as a 128-bit integer

96

97 urn the UUID as a URN as specified in RFC 4122

98

99 variant the UUID variant (one of the constants RESERVED_NCS,

100 RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)

101

102 version the UUID version number (1 through 5, meaningful only

103 when the variant is RFC_4122)

104 """

105

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

106 def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

107 int=None, version=None):

39442

108 r"""Create a UUID from either a string of 32 hexadecimal digits,

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

109 a string of 16 bytes as the 'bytes' argument, a string of 16 bytes

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

110 in little-endian order as the 'bytes_le' argument, a tuple of six

39442

111 integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,

112 8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as

113 the 'fields' argument, or a single 128-bit integer as the 'int'

114 argument. When a string of hex digits is given, curly braces,

115 hyphens, and a URN prefix are all optional. For example, these

116 expressions all yield the same UUID:

117

118 UUID('{12345678-1234-5678-1234-567812345678}')

119 UUID('12345678123456781234567812345678')

120 UUID('urn:uuid:12345678-1234-5678-1234-567812345678')

121 UUID(bytes='\x12\x34\x56\x78'*4)

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

122 UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

123 '\x12\x34\x56\x78\x12\x34\x56\x78')

39442

124 UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))

125 UUID(int=0x12345678123456781234567812345678)

126

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

127 Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

128 be given. The 'version' argument is optional; if given, the resulting

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

129 UUID will have its variant and version set according to RFC 4122,

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

130 overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.

39442

131 """

132

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

133 if [hex, bytes, bytes_le, fields, int].count(None) != 4:

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

134 raise TypeError('need one of hex, bytes, bytes_le, fields, or int')

39442

135 if hex is not None:

136 hex = hex.replace('urn:', '').replace('uuid:', '')

137 hex = hex.strip('{}').replace('-', '')

138 if len(hex) != 32:

139 raise ValueError('badly formed hexadecimal UUID string')

40644

140 int = int_(hex, 16)

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

141 if bytes_le is not None:

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

142 if len(bytes_le) != 16:

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

143 raise ValueError('bytes_le is not a 16-char string')

92368

144 bytes = (bytes_le[4-1::-1] + bytes_le[6-1:4-1:-1] +

145 bytes_le[8-1:6-1:-1] + bytes_le[8:])

39442

146 if bytes is not None:

147 if len(bytes) != 16:

148 raise ValueError('bytes is not a 16-char string')

42164

149 assert isinstance(bytes, bytes_), repr(bytes)

85460

150 int = int_.from_bytes(bytes, byteorder='big')

39442

151 if fields is not None:

152 if len(fields) != 6:

153 raise ValueError('fields is not a 6-tuple')

154 (time_low, time_mid, time_hi_version,

155 clock_seq_hi_variant, clock_seq_low, node) = fields

40644

156 if not 0 <= time_low < 1<<32:

39442

157 raise ValueError('field 1 out of range (need a 32-bit value)')

40644

158 if not 0 <= time_mid < 1<<16:

39442

159 raise ValueError('field 2 out of range (need a 16-bit value)')

40644

160 if not 0 <= time_hi_version < 1<<16:

39442

161 raise ValueError('field 3 out of range (need a 16-bit value)')

40644

162 if not 0 <= clock_seq_hi_variant < 1<<8:

39442

163 raise ValueError('field 4 out of range (need an 8-bit value)')

40644

164 if not 0 <= clock_seq_low < 1<<8:

39442

165 raise ValueError('field 5 out of range (need an 8-bit value)')

40644

166 if not 0 <= node < 1<<48:

39442

167 raise ValueError('field 6 out of range (need a 48-bit value)')

40644

168 clock_seq = (clock_seq_hi_variant << 8) | clock_seq_low

169 int = ((time_low << 96) | (time_mid << 80) |

170 (time_hi_version << 64) | (clock_seq << 48) | node)

39442

171 if int is not None:

40644

172 if not 0 <= int < 1<<128:

39442

173 raise ValueError('int is out of range (need a 128-bit value)')

174 if version is not None:

175 if not 1 <= version <= 5:

176 raise ValueError('illegal version number')

177 # Set the variant to RFC 4122.

40644

178 int &= ~(0xc000 << 48)

179 int |= 0x8000 << 48

39442

180 # Set the version number.

40644

181 int &= ~(0xf000 << 64)

182 int |= version << 76

39442

183 self.__dict__['int'] = int

184

39644

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

185 def __eq__(self, other):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

186 if isinstance(other, UUID):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

187 return self.int == other.int

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

188 return NotImplemented

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

189

42164

190 # Q. What's the value of being able to sort UUIDs?

191 # A. Use them as keys in a B-Tree or similar mapping.

39644

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

192

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

193 def __lt__(self, other):

39442

194 if isinstance(other, UUID):

39644

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

195 return self.int < other.int

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

196 return NotImplemented

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

197

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

198 def __gt__(self, other):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

199 if isinstance(other, UUID):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

200 return self.int > other.int

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

201 return NotImplemented

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

202

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

203 def __le__(self, other):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

204 if isinstance(other, UUID):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

205 return self.int <= other.int

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

206 return NotImplemented

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

207

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

208 def __ge__(self, other):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

209 if isinstance(other, UUID):

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

210 return self.int >= other.int

39442

211 return NotImplemented

212

213 def __hash__(self):

214 return hash(self.int)

215

216 def __int__(self):

217 return self.int

218

219 def __repr__(self):

91870

42276ad3acefIssue #22033: Reprs of most Python implemened classes now contain actual

Serhiy Storchaka storchaka@gmail.com

diff changeset

220 return '%s(%r)' % (self.__class__.__name__, str(self))

39442

221

222 def __setattr__(self, name, value):

223 raise TypeError('UUID objects are immutable')

224

225 def __str__(self):

226 hex = '%032x' % self.int

227 return '%s-%s-%s-%s-%s' % (

228 hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])

229

42164

230 @property

231 def bytes(self):

92368

232 return self.int.to_bytes(16, 'big')

39442

233

42164

234 @property

235 def bytes_le(self):

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

236 bytes = self.bytes

92368

237 return (bytes[4-1::-1] + bytes[6-1:4-1:-1] + bytes[8-1:6-1:-1] +

42164

238 bytes[8:])

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

239

42164

240 @property

241 def fields(self):

39442

242 return (self.time_low, self.time_mid, self.time_hi_version,

243 self.clock_seq_hi_variant, self.clock_seq_low, self.node)

244

42164

245 @property

246 def time_low(self):

40644

247 return self.int >> 96

39442

248

42164

249 @property

250 def time_mid(self):

40644

251 return (self.int >> 80) & 0xffff

39442

252

42164

253 @property

254 def time_hi_version(self):

40644

255 return (self.int >> 64) & 0xffff

39442

256

42164

257 @property

258 def clock_seq_hi_variant(self):

40644

259 return (self.int >> 56) & 0xff

39442

260

42164

261 @property

262 def clock_seq_low(self):

40644

263 return (self.int >> 48) & 0xff

39442

264

42164

265 @property

266 def time(self):

40644

267 return (((self.time_hi_version & 0x0fff) << 48) |

268 (self.time_mid << 32) | self.time_low)

39442

269

42164

270 @property

271 def clock_seq(self):

40644

272 return (((self.clock_seq_hi_variant & 0x3f) << 8) |

39442

273 self.clock_seq_low)

274

42164

275 @property

276 def node(self):

39442

277 return self.int & 0xffffffffffff

278

42164

279 @property

280 def hex(self):

39442

281 return '%032x' % self.int

282

42164

283 @property

284 def urn(self):

39442

285 return 'urn:uuid:' + str(self)

286

42164

287 @property

288 def variant(self):

40644

289 if not self.int & (0x8000 << 48):

39442

290 return RESERVED_NCS

40644

291 elif not self.int & (0x4000 << 48):

39442

292 return RFC_4122

40644

293 elif not self.int & (0x2000 << 48):

39442

294 return RESERVED_MICROSOFT

295 else:

296 return RESERVED_FUTURE

297

42164

298 @property

299 def version(self):

39442

300 # The version bits are only meaningful for RFC 4122 UUIDs.

301 if self.variant == RFC_4122:

40644

302 return int((self.int >> 76) & 0xf)

39442

303

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

304 def _popen(command, *args):

93151

305 import os, shutil, subprocess

88036

b0fbaed45956#19855: uuid.get_node now looks on the PATH for executables on unix.

R David Murray rdmurray@bitdance.com

diff changeset

306 executable = shutil.which(command)

b0fbaed45956#19855: uuid.get_node now looks on the PATH for executables on unix.

R David Murray rdmurray@bitdance.com

diff changeset

307 if executable is None:

b0fbaed45956#19855: uuid.get_node now looks on the PATH for executables on unix.

R David Murray rdmurray@bitdance.com

diff changeset

308 path = os.pathsep.join(('/sbin', '/usr/sbin'))

b0fbaed45956#19855: uuid.get_node now looks on the PATH for executables on unix.

R David Murray rdmurray@bitdance.com

diff changeset

309 executable = shutil.which(command, path=path)

b0fbaed45956#19855: uuid.get_node now looks on the PATH for executables on unix.

R David Murray rdmurray@bitdance.com

diff changeset

310 if executable is None:

b0fbaed45956#19855: uuid.get_node now looks on the PATH for executables on unix.

R David Murray rdmurray@bitdance.com

diff changeset

311 return None

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

312 # LC_ALL=C to ensure English output, stderr=DEVNULL to prevent output

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

313 # on stderr (Note: we don't have an example where the words we search

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

314 # for are actually localized, but in theory some system could do so.)

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

315 env = dict(os.environ)

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

316 env['LC_ALL'] = 'C'

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

317 proc = subprocess.Popen((executable,) + args,

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

318 stdout=subprocess.PIPE,

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

319 stderr=subprocess.DEVNULL,

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

320 env=env)

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

321 return proc

39442

322

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

323 def _find_mac(command, args, hw_identifiers, get_index):

92677

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

324 try:

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

325 proc = _popen(command, *args.split())

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

326 if not proc:

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

327 return

93151

328 with proc:

329 for line in proc.stdout:

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

330 words = line.lower().rstrip().split()

92677

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

331 for i in range(len(words)):

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

332 if words[i] in hw_identifiers:

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

333 try:

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

334 word = words[get_index(i)]

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

335 mac = int(word.replace(b':', b''), 16)

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

336 if mac:

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

337 return mac

92677

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

338 except (ValueError, IndexError):

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

339 # Virtual interfaces, such as those provided by

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

340 # VPNs, do not have a colon-delimited MAC address

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

341 # as expected, but a 16-byte HWAddr separated by

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

342 # dashes. These should be ignored in favor of a

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

343 # real MAC address

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

344 pass

88037

2e856fcb9084Merge: #19855: uuid.get_node now looks on the PATH for executables on unix.

R David Murray rdmurray@bitdance.com

diff changeset

345 except OSError:

92677

f9cd915410d2Issue #19855: uuid.getnode() on Unix now looks on the PATH for the

Georg Brandl georg@python.org

diff changeset

346 pass

39442

347

348 def _ifconfig_getnode():

349 """Get the hardware address on Unix by running ifconfig."""

350 # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.

351 for args in ('', '-a', '-av'):

93151

352 mac = _find_mac('ifconfig', args, [b'hwaddr', b'ether'], lambda i: i+1)

39442

353 if mac:

354 return mac

355

93669

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

356 def _ip_getnode():

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

357 """Get the hardware address on Unix by running ip."""

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

358 # This works on Linux with iproute2.

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

359 mac = _find_mac('ip', 'link list', [b'link/ether'], lambda i: i+1)

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

360 if mac:

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

361 return mac

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

362

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

363 def _arp_getnode():

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

364 """Get the hardware address on Unix by running arp."""

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

365 import os, socket

93531

97ceab0bd6f8Issue #17293: socket.gethostbyname() can raise an exception of FreeBSD.

Serhiy Storchaka storchaka@gmail.com

diff changeset

366 try:

97ceab0bd6f8Issue #17293: socket.gethostbyname() can raise an exception of FreeBSD.

Serhiy Storchaka storchaka@gmail.com

diff changeset

367 ip_addr = socket.gethostbyname(socket.gethostname())

97ceab0bd6f8Issue #17293: socket.gethostbyname() can raise an exception of FreeBSD.

Serhiy Storchaka storchaka@gmail.com

diff changeset

368 except OSError:

97ceab0bd6f8Issue #17293: socket.gethostbyname() can raise an exception of FreeBSD.

Serhiy Storchaka storchaka@gmail.com

diff changeset

369 return None

39442

370

371 # Try getting the MAC addr from arp based on our IP address (Solaris).

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

372 return _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)

39442

373

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

374 def _lanscan_getnode():

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

375 """Get the hardware address on Unix by running lanscan."""

39442

376 # This might work on HP-UX.

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

377 return _find_mac('lanscan', '-ai', [b'lan0'], lambda i: 0)

39442

378

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

379 def _netstat_getnode():

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

380 """Get the hardware address on Unix by running netstat."""

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

381 # This might work on AIX, Tru64 UNIX and presumably on IRIX.

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

382 try:

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

383 proc = _popen('netstat', '-ia')

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

384 if not proc:

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

385 return

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

386 with proc:

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

387 words = proc.stdout.readline().rstrip().split()

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

388 try:

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

389 i = words.index(b'Address')

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

390 except ValueError:

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

391 return

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

392 for line in proc.stdout:

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

393 try:

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

394 words = line.rstrip().split()

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

395 word = words[i]

93426

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

396 if len(word) == 17 and word.count(b':') == 5:

3e4f3cc4f1f9Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

397 mac = int(word.replace(b':', b''), 16)

93425

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

398 if mac:

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

399 return mac

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

400 except (ValueError, IndexError):

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

401 pass

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

402 except OSError:

ba4b31ed2952Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat.

Serhiy Storchaka storchaka@gmail.com

diff changeset

403 pass

39442

404

405 def _ipconfig_getnode():

406 """Get the hardware address on Windows by running ipconfig.exe."""

407 import os, re

408 dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']

409 try:

410 import ctypes

411 buffer = ctypes.create_string_buffer(300)

412 ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)

413 dirs.insert(0, buffer.value.decode('mbcs'))

414 except:

415 pass

416 for dir in dirs:

417 try:

418 pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all')

81039

419 except OSError:

39442

420 continue

92370

8a61a287776dIssue #22131: Fixed a bug in handling an error occured during reading from

Serhiy Storchaka storchaka@gmail.com

diff changeset

421 with pipe:

65963

422 for line in pipe:

423 value = line.split(':')[-1].strip().lower()

424 if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):

425 return int(value.replace('-', ''), 16)

39442

426

427 def _netbios_getnode():

428 """Get the hardware address on Windows using NetBIOS calls.

429 See http://support.microsoft.com/kb/118623 for details."""

430 import win32wnet, netbios

431 ncb = netbios.NCB()

432 ncb.Command = netbios.NCBENUM

433 ncb.Buffer = adapters = netbios.LANA_ENUM()

434 adapters._pack()

435 if win32wnet.Netbios(ncb) != 0:

436 return

437 adapters._unpack()

438 for i in range(adapters.length):

439 ncb.Reset()

440 ncb.Command = netbios.NCBRESET

441 ncb.Lana_num = ord(adapters.lana[i])

442 if win32wnet.Netbios(ncb) != 0:

443 continue

444 ncb.Reset()

445 ncb.Command = netbios.NCBASTAT

446 ncb.Lana_num = ord(adapters.lana[i])

447 ncb.Callname = '*'.ljust(16)

448 ncb.Buffer = status = netbios.ADAPTER_STATUS()

449 if win32wnet.Netbios(ncb) != 0:

450 continue

451 status._unpack()

92368

452 bytes = status.adapter_address[:6]

453 if len(bytes) != 6:

454 continue

455 return int.from_bytes(bytes, 'big')

39442

456

457 # Thanks to Thomas Heller for ctypes and for his help with its use here.

458

459 # If ctypes is available, use it to find system routines for UUID generation.

42328

460 # XXX This makes the module non-thread-safe!

98890

70be1f9c9255always use os.urandom for the uuid4 algorithm (closes #25515)

Benjamin Peterson benjamin@python.org

diff changeset

461 _uuid_generate_time = _UuidCreate = None

39442

462 try:

463 import ctypes, ctypes.util

97330

1df7a0821c73Issue #24634: Importing uuid should not try to load libc on Windows

Steve Dower steve.dower@microsoft.com

diff changeset

464 import sys

39442

465

466 # The uuid_generate_* routines are provided by libuuid on at least

467 # Linux and FreeBSD, and provided by libc on Mac OS X.

97330

1df7a0821c73Issue #24634: Importing uuid should not try to load libc on Windows

Steve Dower steve.dower@microsoft.com

diff changeset

468 _libnames = ['uuid']

1df7a0821c73Issue #24634: Importing uuid should not try to load libc on Windows

Steve Dower steve.dower@microsoft.com

diff changeset

469 if not sys.platform.startswith('win'):

1df7a0821c73Issue #24634: Importing uuid should not try to load libc on Windows

Steve Dower steve.dower@microsoft.com

diff changeset

470 _libnames.append('c')

1df7a0821c73Issue #24634: Importing uuid should not try to load libc on Windows

Steve Dower steve.dower@microsoft.com

diff changeset

471 for libname in _libnames:

39442

472 try:

473 lib = ctypes.CDLL(ctypes.util.find_library(libname))

96166

b3a7215b9ce4Issue #16261: Converted some bare except statements to except statements

Serhiy Storchaka storchaka@gmail.com

diff changeset

474 except Exception:

39442

475 continue

476 if hasattr(lib, 'uuid_generate_time'):

477 _uuid_generate_time = lib.uuid_generate_time

98890

70be1f9c9255always use os.urandom for the uuid4 algorithm (closes #25515)

Benjamin Peterson benjamin@python.org

diff changeset

478 break

97330

1df7a0821c73Issue #24634: Importing uuid should not try to load libc on Windows

Steve Dower steve.dower@microsoft.com

diff changeset

479 del _libnames

39442

480

62547

481 # The uuid_generate_* functions are broken on MacOS X 10.5, as noted

61242

482 # in issue #8621 the function generates the same sequence of values

483 # in the parent process and all children created using fork (unless

484 # those children use exec as well).

485 #

62547

486 # Assume that the uuid_generate functions are broken from 10.5 onward,

61242

487 # the test can be adjusted when a later version is fixed.

488 if sys.platform == 'darwin':

489 import os

77701

460407f35aa9Issue #15118: Change return value of os.uname() and os.times() from

Larry Hastings larry@hastings.org

diff changeset

490 if int(os.uname().release.split('.')[0]) >= 9:

98890

70be1f9c9255always use os.urandom for the uuid4 algorithm (closes #25515)

Benjamin Peterson benjamin@python.org

diff changeset

491 _uuid_generate_time = None

61242

492

39442

493 # On Windows prior to 2000, UuidCreate gives a UUID containing the

494 # hardware address. On Windows 2000 and later, UuidCreate makes a

495 # random UUID and UuidCreateSequential gives a UUID containing the

496 # hardware address. These routines are provided by the RPC runtime.

497 # NOTE: at least on Tim's WinXP Pro SP2 desktop box, while the last

498 # 6 bytes returned by UuidCreateSequential are fixed, they don't appear

499 # to bear any relationship to the MAC address of any network device

500 # on the box.

501 try:

502 lib = ctypes.windll.rpcrt4

503 except:

504 lib = None

505 _UuidCreate = getattr(lib, 'UuidCreateSequential',

506 getattr(lib, 'UuidCreate', None))

507 except:

508 pass

509

510 def _unixdll_getnode():

511 """Get the hardware address on Unix using ctypes."""

42765

512 _buffer = ctypes.create_string_buffer(16)

39442

513 _uuid_generate_time(_buffer)

42328

514 return UUID(bytes=bytes_(_buffer.raw)).node

39442

515

516 def _windll_getnode():

517 """Get the hardware address on Windows using ctypes."""

42765

518 _buffer = ctypes.create_string_buffer(16)

39442

519 if _UuidCreate(_buffer) == 0:

42328

520 return UUID(bytes=bytes_(_buffer.raw)).node

39442

521

522 def _random_getnode():

523 """Get a random node ID, with eighth bit set as suggested by RFC 4122."""

524 import random

92368

525 return random.getrandbits(48) | 0x010000000000

39442

526

527 _node = None

528

529 def getnode():

530 """Get the hardware address as a 48-bit positive integer.

531

532 The first time this runs, it may launch a separate program, which could

533 be quite slow. If all attempts to obtain the hardware address fail, we

534 choose a random 48-bit number with its eighth bit set to 1 as recommended

535 in RFC 4122.

536 """

537

538 global _node

539 if _node is not None:

540 return _node

541

542 import sys

543 if sys.platform == 'win32':

544 getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]

545 else:

93669

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

546 getters = [_unixdll_getnode, _ifconfig_getnode, _ip_getnode,

64bb01bce12cIssue #22902: The "ip" command is now used on Linux to determine MAC address

Serhiy Storchaka storchaka@gmail.com

diff changeset

547 _arp_getnode, _lanscan_getnode, _netstat_getnode]

39442

548

549 for getter in getters + [_random_getnode]:

550 try:

551 _node = getter()

552 except:

553 continue

554 if _node is not None:

555 return _node

556

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

557 _last_timestamp = None

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

558

39442

559 def uuid1(node=None, clock_seq=None):

560 """Generate a UUID from a host ID, sequence number, and the current time.

561 If 'node' is not given, getnode() is used to obtain the hardware

562 address. If 'clock_seq' is given, it is used as the sequence number;

563 otherwise a random 14-bit sequence number is chosen."""

564

565 # When the system provides a version-1 UUID generator, use it (but don't

566 # use UuidCreate here because its UUIDs don't conform to RFC 4122).

567 if _uuid_generate_time and node is clock_seq is None:

49819

630c174b465eMerged revisions 67295,67301-67302,67318,67330,67342-67343 via svnmerge from

Amaury Forgeot d'Arc amauryfa@gmail.com

diff changeset

568 _buffer = ctypes.create_string_buffer(16)

39442

569 _uuid_generate_time(_buffer)

42328

570 return UUID(bytes=bytes_(_buffer.raw))

39442

571

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

572 global _last_timestamp

39442

573 import time

574 nanoseconds = int(time.time() * 1e9)

575 # 0x01b21dd213814000 is the number of 100-ns intervals between the

576 # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.

40644

577 timestamp = int(nanoseconds/100) + 0x01b21dd213814000

39644

13d5e5f0e993Restructure comparison dramatically. There is no longer a default

Guido van Rossum guido@python.org

diff changeset

578 if _last_timestamp is not None and timestamp <= _last_timestamp:

39610

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

579 timestamp = _last_timestamp + 1

3674f20ac781Merge current trunk into p3yk. This includes the PyNumber_Index API change,

Thomas Wouters thomas@python.org

diff changeset

580 _last_timestamp = timestamp

39442

581 if clock_seq is None:

582 import random

92368

583 clock_seq = random.getrandbits(14) # instead of stable storage

40644

584 time_low = timestamp & 0xffffffff

585 time_mid = (timestamp >> 32) & 0xffff

586 time_hi_version = (timestamp >> 48) & 0x0fff

587 clock_seq_low = clock_seq & 0xff

588 clock_seq_hi_variant = (clock_seq >> 8) & 0x3f

39442

589 if node is None:

590 node = getnode()

591 return UUID(fields=(time_low, time_mid, time_hi_version,

592 clock_seq_hi_variant, clock_seq_low, node), version=1)

593

594 def uuid3(namespace, name):

595 """Generate a UUID from the MD5 hash of a namespace UUID and a name."""

41969

596 from hashlib import md5

42164

597 hash = md5(namespace.bytes + bytes(name, "utf-8")).digest()

42166

78203298b42bChange hashlib to return bytes from digest() instead of str8.

Guido van Rossum guido@python.org

diff changeset

598 return UUID(bytes=hash[:16], version=3)

39442

599

600 def uuid4():

601 """Generate a random UUID."""

98890

70be1f9c9255always use os.urandom for the uuid4 algorithm (closes #25515)

Benjamin Peterson benjamin@python.org

diff changeset

602 return UUID(bytes=os.urandom(16), version=4)

39442

603

604 def uuid5(namespace, name):

605 """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""

41969

606 from hashlib import sha1

42164

607 hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()

42166

78203298b42bChange hashlib to return bytes from digest() instead of str8.

Guido van Rossum guido@python.org

diff changeset

608 return UUID(bytes=hash[:16], version=5)

39442

609

610 # The following standard UUIDs are for use with uuid3() or uuid5().

611

612 NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')

613 NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')

614 NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')

615 NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')