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