uuid.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. r"""UUID objects (universally unique identifiers) according to RFC 4122.
  2. This module provides immutable UUID objects (class UUID) and the functions
  3. uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5
  4. UUIDs as specified in RFC 4122.
  5. If all you want is a unique ID, you should probably call uuid1() or uuid4().
  6. Note that uuid1() may compromise privacy since it creates a UUID containing
  7. the computer's network address. uuid4() creates a random UUID.
  8. Typical usage:
  9. >>> import uuid
  10. # make a UUID based on the host ID and current time
  11. >>> uuid.uuid1() # doctest: +SKIP
  12. UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
  13. # make a UUID using an MD5 hash of a namespace UUID and a name
  14. >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
  15. UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
  16. # make a random UUID
  17. >>> uuid.uuid4() # doctest: +SKIP
  18. UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
  19. # make a UUID using a SHA-1 hash of a namespace UUID and a name
  20. >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
  21. UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
  22. # make a UUID from a string of hex digits (braces and hyphens ignored)
  23. >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
  24. # convert a UUID to a string of hex digits in standard form
  25. >>> str(x)
  26. '00010203-0405-0607-0809-0a0b0c0d0e0f'
  27. # get the raw 16 bytes of the UUID
  28. >>> x.bytes
  29. b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
  30. # make a UUID from a 16-byte string
  31. >>> uuid.UUID(bytes=x.bytes)
  32. UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
  33. """
  34. import os
  35. __author__ = 'Ka-Ping Yee <ping@zesty.ca>'
  36. RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
  37. 'reserved for NCS compatibility', 'specified in RFC 4122',
  38. 'reserved for Microsoft compatibility', 'reserved for future definition']
  39. int_ = int # The built-in int type
  40. bytes_ = bytes # The built-in bytes type
  41. class UUID(object):
  42. """Instances of the UUID class represent UUIDs as specified in RFC 4122.
  43. UUID objects are immutable, hashable, and usable as dictionary keys.
  44. Converting a UUID to a string with str() yields something in the form
  45. '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts
  46. five possible forms: a similar string of hexadecimal digits, or a tuple
  47. of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
  48. 48-bit values respectively) as an argument named 'fields', or a string
  49. of 16 bytes (with all the integer fields in big-endian order) as an
  50. argument named 'bytes', or a string of 16 bytes (with the first three
  51. fields in little-endian order) as an argument named 'bytes_le', or a
  52. single 128-bit integer as an argument named 'int'.
  53. UUIDs have these read-only attributes:
  54. bytes the UUID as a 16-byte string (containing the six
  55. integer fields in big-endian byte order)
  56. bytes_le the UUID as a 16-byte string (with time_low, time_mid,
  57. and time_hi_version in little-endian byte order)
  58. fields a tuple of the six integer fields of the UUID,
  59. which are also available as six individual attributes
  60. and two derived attributes:
  61. time_low the first 32 bits of the UUID
  62. time_mid the next 16 bits of the UUID
  63. time_hi_version the next 16 bits of the UUID
  64. clock_seq_hi_variant the next 8 bits of the UUID
  65. clock_seq_low the next 8 bits of the UUID
  66. node the last 48 bits of the UUID
  67. time the 60-bit timestamp
  68. clock_seq the 14-bit sequence number
  69. hex the UUID as a 32-character hexadecimal string
  70. int the UUID as a 128-bit integer
  71. urn the UUID as a URN as specified in RFC 4122
  72. variant the UUID variant (one of the constants RESERVED_NCS,
  73. RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
  74. version the UUID version number (1 through 5, meaningful only
  75. when the variant is RFC_4122)
  76. """
  77. def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
  78. int=None, version=None):
  79. r"""Create a UUID from either a string of 32 hexadecimal digits,
  80. a string of 16 bytes as the 'bytes' argument, a string of 16 bytes
  81. in little-endian order as the 'bytes_le' argument, a tuple of six
  82. integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
  83. 8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
  84. the 'fields' argument, or a single 128-bit integer as the 'int'
  85. argument. When a string of hex digits is given, curly braces,
  86. hyphens, and a URN prefix are all optional. For example, these
  87. expressions all yield the same UUID:
  88. UUID('{12345678-1234-5678-1234-567812345678}')
  89. UUID('12345678123456781234567812345678')
  90. UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
  91. UUID(bytes='\x12\x34\x56\x78'*4)
  92. UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
  93. '\x12\x34\x56\x78\x12\x34\x56\x78')
  94. UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
  95. UUID(int=0x12345678123456781234567812345678)
  96. Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must
  97. be given. The 'version' argument is optional; if given, the resulting
  98. UUID will have its variant and version set according to RFC 4122,
  99. overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.
  100. """
  101. if [hex, bytes, bytes_le, fields, int].count(None) != 4:
  102. raise TypeError('one of the hex, bytes, bytes_le, fields, '
  103. 'or int arguments must be given')
  104. if hex is not None:
  105. hex = hex.replace('urn:', '').replace('uuid:', '')
  106. hex = hex.strip('{}').replace('-', '')
  107. if len(hex) != 32:
  108. raise ValueError('badly formed hexadecimal UUID string')
  109. int = int_(hex, 16)
  110. if bytes_le is not None:
  111. if len(bytes_le) != 16:
  112. raise ValueError('bytes_le is not a 16-char string')
  113. bytes = (bytes_le[4-1::-1] + bytes_le[6-1:4-1:-1] +
  114. bytes_le[8-1:6-1:-1] + bytes_le[8:])
  115. if bytes is not None:
  116. if len(bytes) != 16:
  117. raise ValueError('bytes is not a 16-char string')
  118. assert isinstance(bytes, bytes_), repr(bytes)
  119. int = int_.from_bytes(bytes, byteorder='big')
  120. if fields is not None:
  121. if len(fields) != 6:
  122. raise ValueError('fields is not a 6-tuple')
  123. (time_low, time_mid, time_hi_version,
  124. clock_seq_hi_variant, clock_seq_low, node) = fields
  125. if not 0 <= time_low < 1<<32:
  126. raise ValueError('field 1 out of range (need a 32-bit value)')
  127. if not 0 <= time_mid < 1<<16:
  128. raise ValueError('field 2 out of range (need a 16-bit value)')
  129. if not 0 <= time_hi_version < 1<<16:
  130. raise ValueError('field 3 out of range (need a 16-bit value)')
  131. if not 0 <= clock_seq_hi_variant < 1<<8:
  132. raise ValueError('field 4 out of range (need an 8-bit value)')
  133. if not 0 <= clock_seq_low < 1<<8:
  134. raise ValueError('field 5 out of range (need an 8-bit value)')
  135. if not 0 <= node < 1<<48:
  136. raise ValueError('field 6 out of range (need a 48-bit value)')
  137. clock_seq = (clock_seq_hi_variant << 8) | clock_seq_low
  138. int = ((time_low << 96) | (time_mid << 80) |
  139. (time_hi_version << 64) | (clock_seq << 48) | node)
  140. if int is not None:
  141. if not 0 <= int < 1<<128:
  142. raise ValueError('int is out of range (need a 128-bit value)')
  143. if version is not None:
  144. if not 1 <= version <= 5:
  145. raise ValueError('illegal version number')
  146. # Set the variant to RFC 4122.
  147. int &= ~(0xc000 << 48)
  148. int |= 0x8000 << 48
  149. # Set the version number.
  150. int &= ~(0xf000 << 64)
  151. int |= version << 76
  152. self.__dict__['int'] = int
  153. def __eq__(self, other):
  154. if isinstance(other, UUID):
  155. return self.int == other.int
  156. return NotImplemented
  157. # Q. What's the value of being able to sort UUIDs?
  158. # A. Use them as keys in a B-Tree or similar mapping.
  159. def __lt__(self, other):
  160. if isinstance(other, UUID):
  161. return self.int < other.int
  162. return NotImplemented
  163. def __gt__(self, other):
  164. if isinstance(other, UUID):
  165. return self.int > other.int
  166. return NotImplemented
  167. def __le__(self, other):
  168. if isinstance(other, UUID):
  169. return self.int <= other.int
  170. return NotImplemented
  171. def __ge__(self, other):
  172. if isinstance(other, UUID):
  173. return self.int >= other.int
  174. return NotImplemented
  175. def __hash__(self):
  176. return hash(self.int)
  177. def __int__(self):
  178. return self.int
  179. def __repr__(self):
  180. return '%s(%r)' % (self.__class__.__name__, str(self))
  181. def __setattr__(self, name, value):
  182. raise TypeError('UUID objects are immutable')
  183. def __str__(self):
  184. hex = '%032x' % self.int
  185. return '%s-%s-%s-%s-%s' % (
  186. hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
  187. @property
  188. def bytes(self):
  189. return self.int.to_bytes(16, 'big')
  190. @property
  191. def bytes_le(self):
  192. bytes = self.bytes
  193. return (bytes[4-1::-1] + bytes[6-1:4-1:-1] + bytes[8-1:6-1:-1] +
  194. bytes[8:])
  195. @property
  196. def fields(self):
  197. return (self.time_low, self.time_mid, self.time_hi_version,
  198. self.clock_seq_hi_variant, self.clock_seq_low, self.node)
  199. @property
  200. def time_low(self):
  201. return self.int >> 96
  202. @property
  203. def time_mid(self):
  204. return (self.int >> 80) & 0xffff
  205. @property
  206. def time_hi_version(self):
  207. return (self.int >> 64) & 0xffff
  208. @property
  209. def clock_seq_hi_variant(self):
  210. return (self.int >> 56) & 0xff
  211. @property
  212. def clock_seq_low(self):
  213. return (self.int >> 48) & 0xff
  214. @property
  215. def time(self):
  216. return (((self.time_hi_version & 0x0fff) << 48) |
  217. (self.time_mid << 32) | self.time_low)
  218. @property
  219. def clock_seq(self):
  220. return (((self.clock_seq_hi_variant & 0x3f) << 8) |
  221. self.clock_seq_low)
  222. @property
  223. def node(self):
  224. return self.int & 0xffffffffffff
  225. @property
  226. def hex(self):
  227. return '%032x' % self.int
  228. @property
  229. def urn(self):
  230. return 'urn:uuid:' + str(self)
  231. @property
  232. def variant(self):
  233. if not self.int & (0x8000 << 48):
  234. return RESERVED_NCS
  235. elif not self.int & (0x4000 << 48):
  236. return RFC_4122
  237. elif not self.int & (0x2000 << 48):
  238. return RESERVED_MICROSOFT
  239. else:
  240. return RESERVED_FUTURE
  241. @property
  242. def version(self):
  243. # The version bits are only meaningful for RFC 4122 UUIDs.
  244. if self.variant == RFC_4122:
  245. return int((self.int >> 76) & 0xf)
  246. def _popen(command, *args):
  247. import os, shutil, subprocess
  248. executable = shutil.which(command)
  249. if executable is None:
  250. path = os.pathsep.join(('/sbin', '/usr/sbin'))
  251. executable = shutil.which(command, path=path)
  252. if executable is None:
  253. return None
  254. # LC_ALL=C to ensure English output, stderr=DEVNULL to prevent output
  255. # on stderr (Note: we don't have an example where the words we search
  256. # for are actually localized, but in theory some system could do so.)
  257. env = dict(os.environ)
  258. env['LC_ALL'] = 'C'
  259. proc = subprocess.Popen((executable,) + args,
  260. stdout=subprocess.PIPE,
  261. stderr=subprocess.DEVNULL,
  262. env=env)
  263. return proc
  264. def _find_mac(command, args, hw_identifiers, get_index):
  265. try:
  266. proc = _popen(command, *args.split())
  267. if not proc:
  268. return
  269. with proc:
  270. for line in proc.stdout:
  271. words = line.lower().rstrip().split()
  272. for i in range(len(words)):
  273. if words[i] in hw_identifiers:
  274. try:
  275. word = words[get_index(i)]
  276. mac = int(word.replace(b':', b''), 16)
  277. if mac:
  278. return mac
  279. except (ValueError, IndexError):
  280. # Virtual interfaces, such as those provided by
  281. # VPNs, do not have a colon-delimited MAC address
  282. # as expected, but a 16-byte HWAddr separated by
  283. # dashes. These should be ignored in favor of a
  284. # real MAC address
  285. pass
  286. except OSError:
  287. pass
  288. def _ifconfig_getnode():
  289. """Get the hardware address on Unix by running ifconfig."""
  290. # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
  291. for args in ('', '-a', '-av'):
  292. mac = _find_mac('ifconfig', args, [b'hwaddr', b'ether'], lambda i: i+1)
  293. if mac:
  294. return mac
  295. def _ip_getnode():
  296. """Get the hardware address on Unix by running ip."""
  297. # This works on Linux with iproute2.
  298. mac = _find_mac('ip', 'link list', [b'link/ether'], lambda i: i+1)
  299. if mac:
  300. return mac
  301. def _arp_getnode():
  302. """Get the hardware address on Unix by running arp."""
  303. import os, socket
  304. try:
  305. ip_addr = socket.gethostbyname(socket.gethostname())
  306. except OSError:
  307. return None
  308. # Try getting the MAC addr from arp based on our IP address (Solaris).
  309. return _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
  310. def _lanscan_getnode():
  311. """Get the hardware address on Unix by running lanscan."""
  312. # This might work on HP-UX.
  313. return _find_mac('lanscan', '-ai', [b'lan0'], lambda i: 0)
  314. def _netstat_getnode():
  315. """Get the hardware address on Unix by running netstat."""
  316. # This might work on AIX, Tru64 UNIX and presumably on IRIX.
  317. try:
  318. proc = _popen('netstat', '-ia')
  319. if not proc:
  320. return
  321. with proc:
  322. words = proc.stdout.readline().rstrip().split()
  323. try:
  324. i = words.index(b'Address')
  325. except ValueError:
  326. return
  327. for line in proc.stdout:
  328. try:
  329. words = line.rstrip().split()
  330. word = words[i]
  331. if len(word) == 17 and word.count(b':') == 5:
  332. mac = int(word.replace(b':', b''), 16)
  333. if mac:
  334. return mac
  335. except (ValueError, IndexError):
  336. pass
  337. except OSError:
  338. pass
  339. def _ipconfig_getnode():
  340. """Get the hardware address on Windows by running ipconfig.exe."""
  341. import os, re
  342. dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
  343. try:
  344. import ctypes
  345. buffer = ctypes.create_string_buffer(300)
  346. ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)
  347. dirs.insert(0, buffer.value.decode('mbcs'))
  348. except:
  349. pass
  350. for dir in dirs:
  351. try:
  352. pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all')
  353. except OSError:
  354. continue
  355. with pipe:
  356. for line in pipe:
  357. value = line.split(':')[-1].strip().lower()
  358. if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
  359. return int(value.replace('-', ''), 16)
  360. def _netbios_getnode():
  361. """Get the hardware address on Windows using NetBIOS calls.
  362. See http://support.microsoft.com/kb/118623 for details."""
  363. import win32wnet, netbios
  364. ncb = netbios.NCB()
  365. ncb.Command = netbios.NCBENUM
  366. ncb.Buffer = adapters = netbios.LANA_ENUM()
  367. adapters._pack()
  368. if win32wnet.Netbios(ncb) != 0:
  369. return
  370. adapters._unpack()
  371. for i in range(adapters.length):
  372. ncb.Reset()
  373. ncb.Command = netbios.NCBRESET
  374. ncb.Lana_num = ord(adapters.lana[i])
  375. if win32wnet.Netbios(ncb) != 0:
  376. continue
  377. ncb.Reset()
  378. ncb.Command = netbios.NCBASTAT
  379. ncb.Lana_num = ord(adapters.lana[i])
  380. ncb.Callname = '*'.ljust(16)
  381. ncb.Buffer = status = netbios.ADAPTER_STATUS()
  382. if win32wnet.Netbios(ncb) != 0:
  383. continue
  384. status._unpack()
  385. bytes = status.adapter_address[:6]
  386. if len(bytes) != 6:
  387. continue
  388. return int.from_bytes(bytes, 'big')
  389. # Thanks to Thomas Heller for ctypes and for his help with its use here.
  390. # If ctypes is available, use it to find system routines for UUID generation.
  391. # XXX This makes the module non-thread-safe!
  392. _uuid_generate_time = _UuidCreate = None
  393. try:
  394. import ctypes, ctypes.util
  395. import sys
  396. # The uuid_generate_* routines are provided by libuuid on at least
  397. # Linux and FreeBSD, and provided by libc on Mac OS X.
  398. _libnames = ['uuid']
  399. if not sys.platform.startswith('win'):
  400. _libnames.append('c')
  401. for libname in _libnames:
  402. try:
  403. lib = ctypes.CDLL(ctypes.util.find_library(libname))
  404. except Exception:
  405. continue
  406. if hasattr(lib, 'uuid_generate_time'):
  407. _uuid_generate_time = lib.uuid_generate_time
  408. break
  409. del _libnames
  410. # The uuid_generate_* functions are broken on MacOS X 10.5, as noted
  411. # in issue #8621 the function generates the same sequence of values
  412. # in the parent process and all children created using fork (unless
  413. # those children use exec as well).
  414. #
  415. # Assume that the uuid_generate functions are broken from 10.5 onward,
  416. # the test can be adjusted when a later version is fixed.
  417. if sys.platform == 'darwin':
  418. import os
  419. if int(os.uname().release.split('.')[0]) >= 9:
  420. _uuid_generate_time = None
  421. # On Windows prior to 2000, UuidCreate gives a UUID containing the
  422. # hardware address. On Windows 2000 and later, UuidCreate makes a
  423. # random UUID and UuidCreateSequential gives a UUID containing the
  424. # hardware address. These routines are provided by the RPC runtime.
  425. # NOTE: at least on Tim's WinXP Pro SP2 desktop box, while the last
  426. # 6 bytes returned by UuidCreateSequential are fixed, they don't appear
  427. # to bear any relationship to the MAC address of any network device
  428. # on the box.
  429. try:
  430. lib = ctypes.windll.rpcrt4
  431. except:
  432. lib = None
  433. _UuidCreate = getattr(lib, 'UuidCreateSequential',
  434. getattr(lib, 'UuidCreate', None))
  435. except:
  436. pass
  437. def _unixdll_getnode():
  438. """Get the hardware address on Unix using ctypes."""
  439. _buffer = ctypes.create_string_buffer(16)
  440. _uuid_generate_time(_buffer)
  441. return UUID(bytes=bytes_(_buffer.raw)).node
  442. def _windll_getnode():
  443. """Get the hardware address on Windows using ctypes."""
  444. _buffer = ctypes.create_string_buffer(16)
  445. if _UuidCreate(_buffer) == 0:
  446. return UUID(bytes=bytes_(_buffer.raw)).node
  447. def _random_getnode():
  448. """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
  449. import random
  450. return random.getrandbits(48) | 0x010000000000
  451. _node = None
  452. def getnode():
  453. """Get the hardware address as a 48-bit positive integer.
  454. The first time this runs, it may launch a separate program, which could
  455. be quite slow. If all attempts to obtain the hardware address fail, we
  456. choose a random 48-bit number with its eighth bit set to 1 as recommended
  457. in RFC 4122.
  458. """
  459. global _node
  460. if _node is not None:
  461. return _node
  462. import sys
  463. if sys.platform == 'win32':
  464. getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
  465. else:
  466. getters = [_unixdll_getnode, _ifconfig_getnode, _ip_getnode,
  467. _arp_getnode, _lanscan_getnode, _netstat_getnode]
  468. for getter in getters + [_random_getnode]:
  469. try:
  470. _node = getter()
  471. except:
  472. continue
  473. if _node is not None:
  474. return _node
  475. _last_timestamp = None
  476. def uuid1(node=None, clock_seq=None):
  477. """Generate a UUID from a host ID, sequence number, and the current time.
  478. If 'node' is not given, getnode() is used to obtain the hardware
  479. address. If 'clock_seq' is given, it is used as the sequence number;
  480. otherwise a random 14-bit sequence number is chosen."""
  481. # When the system provides a version-1 UUID generator, use it (but don't
  482. # use UuidCreate here because its UUIDs don't conform to RFC 4122).
  483. if _uuid_generate_time and node is clock_seq is None:
  484. _buffer = ctypes.create_string_buffer(16)
  485. _uuid_generate_time(_buffer)
  486. return UUID(bytes=bytes_(_buffer.raw))
  487. global _last_timestamp
  488. import time
  489. nanoseconds = int(time.time() * 1e9)
  490. # 0x01b21dd213814000 is the number of 100-ns intervals between the
  491. # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
  492. timestamp = int(nanoseconds/100) + 0x01b21dd213814000
  493. if _last_timestamp is not None and timestamp <= _last_timestamp:
  494. timestamp = _last_timestamp + 1
  495. _last_timestamp = timestamp
  496. if clock_seq is None:
  497. import random
  498. clock_seq = random.getrandbits(14) # instead of stable storage
  499. time_low = timestamp & 0xffffffff
  500. time_mid = (timestamp >> 32) & 0xffff
  501. time_hi_version = (timestamp >> 48) & 0x0fff
  502. clock_seq_low = clock_seq & 0xff
  503. clock_seq_hi_variant = (clock_seq >> 8) & 0x3f
  504. if node is None:
  505. node = getnode()
  506. return UUID(fields=(time_low, time_mid, time_hi_version,
  507. clock_seq_hi_variant, clock_seq_low, node), version=1)
  508. def uuid3(namespace, name):
  509. """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
  510. from hashlib import md5
  511. hash = md5(namespace.bytes + bytes(name, "utf-8")).digest()
  512. return UUID(bytes=hash[:16], version=3)
  513. def uuid4():
  514. """Generate a random UUID."""
  515. return UUID(bytes=os.urandom(16), version=4)
  516. def uuid5(namespace, name):
  517. """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
  518. from hashlib import sha1
  519. hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()
  520. return UUID(bytes=hash[:16], version=5)
  521. # The following standard UUIDs are for use with uuid3() or uuid5().
  522. NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
  523. NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
  524. NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
  525. NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')