utils/rtc-template/uuid.py
Go to the documentation of this file.
1 r"""UUID objects (universally unique identifiers) according to RFC 4122.
2 
3 This module provides immutable UUID objects (class UUID) and the functions
4 uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5
5 UUIDs as specified in RFC 4122.
6 
7 If all you want is a unique ID, you should probably call uuid1() or uuid4().
8 Note that uuid1() may compromise privacy since it creates a UUID containing
9 the computer's network address. uuid4() creates a random UUID.
10 
11 Typical usage:
12 
13  >>> import uuid
14 
15  # make a UUID based on the host ID and current time
16  >>> uuid.uuid1()
17  UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
18 
19  # make a UUID using an MD5 hash of a namespace UUID and a name
20  >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
21  UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
22 
23  # make a random UUID
24  >>> uuid.uuid4()
25  UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
26 
27  # make a UUID using a SHA-1 hash of a namespace UUID and a name
28  >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
29  UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
30 
31  # make a UUID from a string of hex digits (braces and hyphens ignored)
32  >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
33 
34  # convert a UUID to a string of hex digits in standard form
35  >>> str(x)
36  '00010203-0405-0607-0809-0a0b0c0d0e0f'
37 
38  # get the raw 16 bytes of the UUID
39  >>> x.bytes
40  '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
41 
42  # make a UUID from a 16-byte string
43  >>> uuid.UUID(bytes=x.bytes)
44  UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
45 
46 This module works with Python 2.3 or higher."""
47 
48 __author__ = 'Ka-Ping Yee <ping@zesty.ca>'
49 __date__ = '$Date: 2007-07-20 16:16:21 $'.split()[1].replace('/', '-')
50 __version__ = '$Revision: 1.1.2.1 $'.split()[1]
51 
52 RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
53  'reserved for NCS compatibility', 'specified in RFC 4122',
54  'reserved for Microsoft compatibility', 'reserved for future definition']
55 
56 class UUID(object):
57  """Instances of the UUID class represent UUIDs as specified in RFC 4122.
58  UUID objects are immutable, hashable, and usable as dictionary keys.
59  Converting a UUID to a string with str() yields something in the form
60  '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts
61  four possible forms: a similar string of hexadecimal digits, or a
62  string of 16 raw bytes as an argument named 'bytes', or a tuple of
63  six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
64  48-bit values respectively) as an argument named 'fields', or a single
65  128-bit integer as an argument named 'int'.
66 
67  UUIDs have these read-only attributes:
68 
69  bytes the UUID as a 16-byte string
70 
71  fields a tuple of the six integer fields of the UUID,
72  which are also available as six individual attributes
73  and two derived attributes:
74 
75  time_low the first 32 bits of the UUID
76  time_mid the next 16 bits of the UUID
77  time_hi_version the next 16 bits of the UUID
78  clock_seq_hi_variant the next 8 bits of the UUID
79  clock_seq_low the next 8 bits of the UUID
80  node the last 48 bits of the UUID
81 
82  time the 60-bit timestamp
83  clock_seq the 14-bit sequence number
84 
85  hex the UUID as a 32-character hexadecimal string
86 
87  int the UUID as a 128-bit integer
88 
89  urn the UUID as a URN as specified in RFC 4122
90 
91  variant the UUID variant (one of the constants RESERVED_NCS,
92  RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
93 
94  version the UUID version number (1 through 5, meaningful only
95  when the variant is RFC_4122)
96  """
97 
98  def __init__(self, hex=None, bytes=None, fields=None, int=None,
99  version=None):
100  r"""Create a UUID from either a string of 32 hexadecimal digits,
101  a string of 16 bytes as the 'bytes' argument, a tuple of six
102  integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
103  8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
104  the 'fields' argument, or a single 128-bit integer as the 'int'
105  argument. When a string of hex digits is given, curly braces,
106  hyphens, and a URN prefix are all optional. For example, these
107  expressions all yield the same UUID:
108 
109  UUID('{12345678-1234-5678-1234-567812345678}')
110  UUID('12345678123456781234567812345678')
111  UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
112  UUID(bytes='\x12\x34\x56\x78'*4)
113  UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
114  UUID(int=0x12345678123456781234567812345678)
115 
116  Exactly one of 'hex', 'bytes', 'fields', or 'int' must be given.
117  The 'version' argument is optional; if given, the resulting UUID
118  will have its variant and version number set according to RFC 4122,
119  overriding bits in the given 'hex', 'bytes', 'fields', or 'int'.
120  """
121 
122  if [hex, bytes, fields, int].count(None) != 3:
123  raise TypeError('need just one of hex, bytes, fields, or int')
124  if hex is not None:
125  hex = hex.replace('urn:', '').replace('uuid:', '')
126  hex = hex.strip('{}').replace('-', '')
127  if len(hex) != 32:
128  raise ValueError('badly formed hexadecimal UUID string')
129  int = long(hex, 16)
130  if bytes is not None:
131  if len(bytes) != 16:
132  raise ValueError('bytes is not a 16-char string')
133  int = long(('%02x'*16) % tuple(map(ord, bytes)), 16)
134  if fields is not None:
135  if len(fields) != 6:
136  raise ValueError('fields is not a 6-tuple')
137  (time_low, time_mid, time_hi_version,
138  clock_seq_hi_variant, clock_seq_low, node) = fields
139  if not 0 <= time_low < 1<<32L:
140  raise ValueError('field 1 out of range (need a 32-bit value)')
141  if not 0 <= time_mid < 1<<16L:
142  raise ValueError('field 2 out of range (need a 16-bit value)')
143  if not 0 <= time_hi_version < 1<<16L:
144  raise ValueError('field 3 out of range (need a 16-bit value)')
145  if not 0 <= clock_seq_hi_variant < 1<<8L:
146  raise ValueError('field 4 out of range (need an 8-bit value)')
147  if not 0 <= clock_seq_low < 1<<8L:
148  raise ValueError('field 5 out of range (need an 8-bit value)')
149  if not 0 <= node < 1<<48L:
150  raise ValueError('field 6 out of range (need a 48-bit value)')
151  clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low
152  int = ((time_low << 96L) | (time_mid << 80L) |
153  (time_hi_version << 64L) | (clock_seq << 48L) | node)
154  if int is not None:
155  if not 0 <= int < 1<<128L:
156  raise ValueError('int is out of range (need a 128-bit value)')
157  if version is not None:
158  if not 1 <= version <= 5:
159  raise ValueError('illegal version number')
160  # Set the variant to RFC 4122.
161  int &= ~(0xc000 << 48L)
162  int |= 0x8000 << 48L
163  # Set the version number.
164  int &= ~(0xf000 << 64L)
165  int |= version << 76L
166  self.__dict__['int'] = int
167 
168  def __cmp__(self, other):
169  if isinstance(other, UUID):
170  return cmp(self.int, other.int)
171  return NotImplemented
172 
173  def __hash__(self):
174  return hash(self.int)
175 
176  def __int__(self):
177  return self.int
178 
179  def __repr__(self):
180  return 'UUID(%r)' % str(self)
181 
182  def __setattr__(self, name, value):
183  raise TypeError('UUID objects are immutable')
184 
185  def __str__(self):
186  hex = '%032x' % self.int
187  return '%s-%s-%s-%s-%s' % (
188  hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
189 
190  def get_bytes(self):
191  bytes = ''
192  for shift in range(0, 128, 8):
193  bytes = chr((self.int >> shift) & 0xff) + bytes
194  return bytes
195 
196  bytes = property(get_bytes)
197 
198  def get_fields(self):
199  return (self.time_low, self.time_mid, self.time_hi_version,
200  self.clock_seq_hi_variant, self.clock_seq_low, self.node)
201 
202  fields = property(get_fields)
203 
204  def get_time_low(self):
205  return self.int >> 96L
206 
207  time_low = property(get_time_low)
208 
209  def get_time_mid(self):
210  return (self.int >> 80L) & 0xffff
211 
212  time_mid = property(get_time_mid)
213 
215  return (self.int >> 64L) & 0xffff
216 
217  time_hi_version = property(get_time_hi_version)
218 
220  return (self.int >> 56L) & 0xff
221 
222  clock_seq_hi_variant = property(get_clock_seq_hi_variant)
223 
224  def get_clock_seq_low(self):
225  return (self.int >> 48L) & 0xff
226 
227  clock_seq_low = property(get_clock_seq_low)
228 
229  def get_time(self):
230  return (((self.time_hi_version & 0x0fffL) << 48L) |
231  (self.time_mid << 32L) | self.time_low)
232 
233  time = property(get_time)
234 
235  def get_clock_seq(self):
236  return (((self.clock_seq_hi_variant & 0x3fL) << 8L) |
237  self.clock_seq_low)
238 
239  clock_seq = property(get_clock_seq)
240 
241  def get_node(self):
242  return self.int & 0xffffffffffff
243 
244  node = property(get_node)
245 
246  def get_hex(self):
247  return '%032x' % self.int
248 
249  hex = property(get_hex)
250 
251  def get_urn(self):
252  return 'urn:uuid:' + str(self)
253 
254  urn = property(get_urn)
255 
256  def get_variant(self):
257  if not self.int & (0x8000 << 48L):
258  return RESERVED_NCS
259  elif not self.int & (0x4000 << 48L):
260  return RFC_4122
261  elif not self.int & (0x2000 << 48L):
262  return RESERVED_MICROSOFT
263  else:
264  return RESERVED_FUTURE
265 
266  variant = property(get_variant)
267 
268  def get_version(self):
269  # The version bits are only meaningful for RFC 4122 UUIDs.
270  if self.variant == RFC_4122:
271  return int((self.int >> 76L) & 0xf)
272 
273  version = property(get_version)
274 
275 def _ifconfig_getnode():
276  """Get the hardware address on Unix by running ifconfig."""
277  import os
278  dir = '/sbin/'
279  pipe = os.popen(os.path.join(dir, 'ifconfig'))
280 
281  for line in pipe:
282  words = line.lower().split()
283  for i in range(len(words)):
284  if words[i] in ['hwaddr', 'ether']:
285  return int(words[i + 1].replace(':', ''), 16)
286 
287 def _ipconfig_getnode():
288  """Get the hardware address on Windows by running ipconfig.exe."""
289  import os, re
290  dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
291  try:
292  import ctypes
293  buffer = ctypes.create_string_buffer(300)
294  ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)
295  dirs.insert(0, buffer.value.decode('mbcs'))
296  except:
297  pass
298  for dir in dirs:
299  try:
300  pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all')
301  except IOError:
302  continue
303  for line in pipe:
304  value = line.split(':')[-1].strip().lower()
305  if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
306  return int(value.replace('-', ''), 16)
307 
308 def _netbios_getnode():
309  """Get the hardware address on Windows using NetBIOS calls.
310  See http://support.microsoft.com/kb/118623 for details."""
311  import win32wnet, netbios
312  ncb = netbios.NCB()
313  ncb.Command = netbios.NCBENUM
314  ncb.Buffer = adapters = netbios.LANA_ENUM()
315  adapters._pack()
316  if win32wnet.Netbios(ncb) != 0:
317  return
318  adapters._unpack()
319  for i in range(adapters.length):
320  ncb.Reset()
321  ncb.Command = netbios.NCBRESET
322  ncb.Lana_num = ord(adapters.lana[i])
323  if win32wnet.Netbios(ncb) != 0:
324  continue
325  ncb.Reset()
326  ncb.Command = netbios.NCBASTAT
327  ncb.Lana_num = ord(adapters.lana[i])
328  ncb.Callname = '*'.ljust(16)
329  ncb.Buffer = status = netbios.ADAPTER_STATUS()
330  if win32wnet.Netbios(ncb) != 0:
331  continue
332  status._unpack()
333  bytes = map(ord, status.adapter_address)
334  return ((bytes[0]<<40L) + (bytes[1]<<32L) + (bytes[2]<<24L) +
335  (bytes[3]<<16L) + (bytes[4]<<8L) + bytes[5])
336 
337 # Thanks to Thomas Heller for ctypes and for his help with its use here.
338 
339 # If ctypes is available, use it to find system routines for UUID generation.
340 _uuid_generate_random = _uuid_generate_time = _UuidCreate = None
341 try:
342  import ctypes, ctypes.util
343  _buffer = ctypes.create_string_buffer(16)
344 
345  # The uuid_generate_* routines are provided by libuuid on at least
346  # Linux and FreeBSD, and provided by libc on Mac OS X.
347  for libname in ['uuid', 'c']:
348  try:
349  lib = ctypes.CDLL(ctypes.util.find_library(libname))
350  except:
351  continue
352  if hasattr(lib, 'uuid_generate_random'):
353  _uuid_generate_random = lib.uuid_generate_random
354  if hasattr(lib, 'uuid_generate_time'):
355  _uuid_generate_time = lib.uuid_generate_time
356 
357  # On Windows prior to 2000, UuidCreate gives a UUID containing the
358  # hardware address. On Windows 2000 and later, UuidCreate makes a
359  # random UUID and UuidCreateSequential gives a UUID containing the
360  # hardware address. These routines are provided by the RPC runtime.
361  try:
362  lib = ctypes.windll.rpcrt4
363  except:
364  lib = None
365  _UuidCreate = getattr(lib, 'UuidCreateSequential',
366  getattr(lib, 'UuidCreate', None))
367 except:
368  pass
369 
370 def _unixdll_getnode():
371  """Get the hardware address on Unix using ctypes."""
372  _uuid_generate_time(_buffer)
373  return UUID(bytes=_buffer.raw).node
374 
375 def _windll_getnode():
376  """Get the hardware address on Windows using ctypes."""
377  if _UuidCreate(_buffer) == 0:
378  return UUID(bytes=_buffer.raw).node
379 
380 def _random_getnode():
381  """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
382  import random
383  return random.randrange(0, 1<<48L) | 0x010000000000L
384 
385 _node = None
386 
387 def getnode():
388  """Get the hardware address as a 48-bit integer. The first time this
389  runs, it may launch a separate program, which could be quite slow. If
390  all attempts to obtain the hardware address fail, we choose a random
391  48-bit number with its eighth bit set to 1 as recommended in RFC 4122."""
392 
393  global _node
394  if _node is not None:
395  return _node
396 
397  import sys
398  if sys.platform == 'win32':
399  getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
400  else:
401  getters = [_unixdll_getnode, _ifconfig_getnode]
402 
403  for getter in getters + [_random_getnode]:
404  try:
405  _node = getter()
406  except:
407  continue
408  if _node is not None:
409  return _node
410 
411 def uuid1(node=None, clock_seq=None):
412  """Generate a UUID from a host ID, sequence number, and the current time.
413  If 'node' is not given, getnode() is used to obtain the hardware
414  address. If 'clock_seq' is given, it is used as the sequence number;
415  otherwise a random 14-bit sequence number is chosen."""
416 
417  # When the system provides a version-1 UUID generator, use it (but don't
418  # use UuidCreate here because its UUIDs don't conform to RFC 4122).
419  if _uuid_generate_time and node is clock_seq is None:
420  _uuid_generate_time(_buffer)
421  return UUID(bytes=_buffer.raw)
422 
423  import time
424  nanoseconds = int(time.time() * 1e9)
425  # 0x01b21dd213814000 is the number of 100-ns intervals between the
426  # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
427  timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
428  if clock_seq is None:
429  import random
430  clock_seq = random.randrange(1<<14L) # instead of stable storage
431  time_low = timestamp & 0xffffffffL
432  time_mid = (timestamp >> 32L) & 0xffffL
433  time_hi_version = (timestamp >> 48L) & 0x0fffL
434  clock_seq_low = clock_seq & 0xffL
435  clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL
436  if node is None:
437  node = getnode()
438  return UUID(fields=(time_low, time_mid, time_hi_version,
439  clock_seq_hi_variant, clock_seq_low, node), version=1)
440 
441 def uuid3(namespace, name):
442  """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
443  import md5
444  hash = md5.md5(namespace.bytes + name).digest()
445  return UUID(bytes=hash[:16], version=3)
446 
447 def uuid4():
448  """Generate a random UUID."""
449 
450  # When the system provides a version-4 UUID generator, use it.
451  if _uuid_generate_random:
452  _uuid_generate_random(_buffer)
453  return UUID(bytes=_buffer.raw)
454 
455  # Otherwise, get randomness from urandom or the 'random' module.
456  try:
457  import os
458  return UUID(bytes=os.urandom(16), version=4)
459  except:
460  import random
461  bytes = [chr(random.randrange(256)) for i in range(16)]
462  return UUID(bytes=bytes, version=4)
463 
464 def uuid5(namespace, name):
465  """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
466  import sha
467  hash = sha.sha(namespace.bytes + name).digest()
468  return UUID(bytes=hash[:16], version=5)
469 
470 # The following standard UUIDs are for use with uuid3() or uuid5().
471 
472 NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
473 NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
474 NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
475 NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')
def _ipconfig_getnode()
def uuid1(node=None, clock_seq=None)
def __setattr__(self, name, value)
vstring split(const std::string &input, const std::string &delimiter, bool ignore_empty)
Split string by delimiter.
Definition: stringutil.cpp:346
def uuid5(namespace, name)
def get_time_hi_version(self)
def __init__(self)
Definition: RtmParser.py:319
def _ifconfig_getnode()
ACE_Utils::UUID UUID
Definition: ace/coil/UUID.h:36
def __cmp__(self, other)
def uuid3(namespace, name)
def get_clock_seq_hi_variant(self)
def get_clock_seq_low(self)
def _unixdll_getnode()
def _netbios_getnode()


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Mon Feb 28 2022 23:00:45