OpenRTM_aist/uuid.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- coding: euc-jp -*-
3 
4 
16 
17 
18 RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
19  'reserved for NCS compatibility', 'specified in RFC 4122',
20  'reserved for Microsoft compatibility', 'reserved for future definition']
21 
22 
34 class UUID(object):
35 
36  def __init__(self, hex=None, bytes=None, fields=None, int=None,
37  version=None):
38  r"""Create a UUID from either a string of 32 hexadecimal digits,
39  a string of 16 bytes as the 'bytes' argument, a tuple of six
40  integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
41  8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
42  the 'fields' argument, or a single 128-bit integer as the 'int'
43  argument. When a string of hex digits is given, curly braces,
44  hyphens, and a URN prefix are all optional. For example, these
45  expressions all yield the same UUID:
46 
47  UUID('{12345678-1234-5678-1234-567812345678}')
48  UUID('12345678123456781234567812345678')
49  UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
50  UUID(bytes='\x12\x34\x56\x78'*4)
51  UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
52  UUID(int=0x12345678123456781234567812345678)
53 
54  Exactly one of 'hex', 'bytes', 'fields', or 'int' must be given.
55  The 'version' argument is optional; if given, the resulting UUID
56  will have its variant and version number set according to RFC 4122,
57  overriding bits in the given 'hex', 'bytes', 'fields', or 'int'.
58  """
59 
60  if [hex, bytes, fields, int].count(None) != 3:
61  raise TypeError('need just one of hex, bytes, fields, or int')
62  if hex:
63  hex = hex.replace('urn:', '').replace('uuid:', '')
64  hex = hex.strip('{}').replace('-', '')
65  if len(hex) != 32:
66  raise ValueError('badly formed hexadecimal UUID string')
67  int = long(hex, 16)
68  if bytes:
69  if len(bytes) != 16:
70  raise ValueError('bytes is not a 16-char string')
71  int = long(('%02x'*16) % tuple(map(ord, bytes)), 16)
72  if fields:
73  if len(fields) != 6:
74  raise ValueError('fields is not a 6-tuple')
75  (time_low, time_mid, time_hi_version,
76  clock_seq_hi_variant, clock_seq_low, node) = fields
77  if not 0 <= time_low < 1<<32L:
78  raise ValueError('field 1 out of range (need a 32-bit value)')
79  if not 0 <= time_mid < 1<<16L:
80  raise ValueError('field 2 out of range (need a 16-bit value)')
81  if not 0 <= time_hi_version < 1<<16L:
82  raise ValueError('field 3 out of range (need a 16-bit value)')
83  if not 0 <= clock_seq_hi_variant < 1<<8L:
84  raise ValueError('field 4 out of range (need an 8-bit value)')
85  if not 0 <= clock_seq_low < 1<<8L:
86  raise ValueError('field 5 out of range (need an 8-bit value)')
87  if not 0 <= node < 1<<48L:
88  raise ValueError('field 6 out of range (need a 48-bit value)')
89  clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low
90  int = ((time_low << 96L) | (time_mid << 80L) |
91  (time_hi_version << 64L) | (clock_seq << 48L) | node)
92  if int:
93  if not 0 <= int < 1<<128L:
94  raise ValueError('int is out of range (need a 128-bit value)')
95  if version:
96  if not 1 <= version <= 5:
97  raise ValueError('illegal version number')
98  # Set the variant to RFC 4122.
99  int &= ~(0xc000 << 48L)
100  int |= 0x8000 << 48L
101  # Set the version number.
102  int &= ~(0xf000 << 64L)
103  int |= version << 76L
104  self.__dict__['int'] = int
105 
106  def __cmp__(self, other):
107  if isinstance(other, UUID):
108  return cmp(self.int, other.int)
109  return NotImplemented
110 
111  def __hash__(self):
112  return hash(self.int)
113 
114  def __int__(self):
115  return self.int
116 
117  def __repr__(self):
118  return 'UUID(%r)' % str(self)
119 
120  def __setattr__(self, name, value):
121  raise TypeError('UUID objects are immutable')
122 
123  def __str__(self):
124  hex = '%032x' % self.int
125  return '%s-%s-%s-%s-%s' % (
126  hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
127 
128  def get_bytes(self):
129  bytes = ''
130  for shift in range(0, 128, 8):
131  bytes = chr((self.int >> shift) & 0xff) + bytes
132  return bytes
133 
134  bytes = property(get_bytes)
135 
136  def get_fields(self):
137  return (self.time_low, self.time_mid, self.time_hi_version,
138  self.clock_seq_hi_variant, self.clock_seq_low, self.node)
139 
140  fields = property(get_fields)
141 
142  def get_time_low(self):
143  return self.int >> 96L
144 
145  time_low = property(get_time_low)
146 
147  def get_time_mid(self):
148  return (self.int >> 80L) & 0xffff
149 
150  time_mid = property(get_time_mid)
151 
153  return (self.int >> 64L) & 0xffff
154 
155  time_hi_version = property(get_time_hi_version)
156 
158  return (self.int >> 56L) & 0xff
159 
160  clock_seq_hi_variant = property(get_clock_seq_hi_variant)
161 
162  def get_clock_seq_low(self):
163  return (self.int >> 48L) & 0xff
164 
165  clock_seq_low = property(get_clock_seq_low)
166 
167  def get_time(self):
168  return (((self.time_hi_version & 0x0fffL) << 48L) |
169  (self.time_mid << 32L) | self.time_low)
170 
171  time = property(get_time)
172 
173  def get_clock_seq(self):
174  return (((self.clock_seq_hi_variant & 0x3fL) << 8L) |
175  self.clock_seq_low)
176 
177  clock_seq = property(get_clock_seq)
178 
179  def get_node(self):
180  return self.int & 0xffffffffffff
181 
182  node = property(get_node)
183 
184  def get_hex(self):
185  return '%032x' % self.int
186 
187  hex = property(get_hex)
188 
189  def get_urn(self):
190  return 'urn:uuid:' + str(self)
191 
192  urn = property(get_urn)
193 
194  def get_variant(self):
195  if not self.int & (0x8000 << 48L):
196  return RESERVED_NCS
197  elif not self.int & (0x4000 << 48L):
198  return RFC_4122
199  elif not self.int & (0x2000 << 48L):
200  return RESERVED_MICROSOFT
201  else:
202  return RESERVED_FUTURE
203 
204  variant = property(get_variant)
205 
206  def get_version(self):
207  # The version bits are only meaningful for RFC 4122 UUIDs.
208  if self.variant == RFC_4122:
209  return int((self.int >> 76L) & 0xf)
210 
211  version = property(get_version)
212 
214  """Get the hardware address on Unix by running ifconfig."""
215  import os
216  dir = '/sbin/'
217  pipe = os.popen(os.path.join(dir, 'ifconfig'))
218 
219  for line in pipe:
220  words = line.lower().split()
221  for i in range(len(words)):
222  if words[i] in ['hwaddr', 'ether']:
223  return int(words[i + 1].replace(':', ''), 16)
224 
226  """Get the hardware address on Windows by running ipconfig.exe."""
227  import os, re
228  dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
229  try:
230  import ctypes
231  buffer = ctypes.create_string_buffer(300)
232  ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)
233  dirs.insert(0, buffer.value.decode('mbcs'))
234  except:
235  pass
236  for dir in dirs:
237  try:
238  pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all')
239  except IOError:
240  continue
241  for line in pipe:
242  value = line.split(':')[-1].strip().lower()
243  if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
244  return int(value.replace('-', ''), 16)
245 
247  """Get the hardware address on Windows using NetBIOS calls.
248  See http://support.microsoft.com/kb/118623 for details."""
249  import win32wnet, netbios
250  ncb = netbios.NCB()
251  ncb.Command = netbios.NCBENUM
252  ncb.Buffer = adapters = netbios.LANA_ENUM()
253  adapters._pack()
254  if win32wnet.Netbios(ncb) != 0:
255  return
256  adapters._unpack()
257  for i in range(adapters.length):
258  ncb.Reset()
259  ncb.Command = netbios.NCBRESET
260  ncb.Lana_num = ord(adapters.lana[i])
261  if win32wnet.Netbios(ncb) != 0:
262  continue
263  ncb.Reset()
264  ncb.Command = netbios.NCBASTAT
265  ncb.Lana_num = ord(adapters.lana[i])
266  ncb.Callname = '*'.ljust(16)
267  ncb.Buffer = status = netbios.ADAPTER_STATUS()
268  if win32wnet.Netbios(ncb) != 0:
269  continue
270  status._unpack()
271  bytes = map(ord, status.adapter_address)
272  return ((bytes[0]<<40L) + (bytes[1]<<32L) + (bytes[2]<<24L) +
273  (bytes[3]<<16L) + (bytes[4]<<8L) + bytes[5])
274 
275 # Thanks to Thomas Heller for ctypes and for his help with its use here.
276 
277 # If ctypes is available, use it to find system routines for UUID generation.
278 _uuid_generate_random = _uuid_generate_time = _UuidCreate = None
279 try:
280  import ctypes, ctypes.util
281  _buffer = ctypes.create_string_buffer(16)
282 
283  # The uuid_generate_* routines are provided by libuuid on at least
284  # Linux and FreeBSD, and provided by libc on Mac OS X.
285  for libname in ['uuid', 'c']:
286  try:
287  lib = ctypes.CDLL(ctypes.util.find_library(libname))
288  except:
289  continue
290  if hasattr(lib, 'uuid_generate_random'):
291  _uuid_generate_random = lib.uuid_generate_random
292  if hasattr(lib, 'uuid_generate_time'):
293  _uuid_generate_time = lib.uuid_generate_time
294 
295  # On Windows prior to 2000, UuidCreate gives a UUID containing the
296  # hardware address. On Windows 2000 and later, UuidCreate makes a
297  # random UUID and UuidCreateSequential gives a UUID containing the
298  # hardware address. These routines are provided by the RPC runtime.
299  try:
300  lib = ctypes.windll.rpcrt4
301  except:
302  lib = None
303  _UuidCreate = getattr(lib, 'UuidCreateSequential',
304  getattr(lib, 'UuidCreate', None))
305 except:
306  pass
307 
309  """Get the hardware address on Unix using ctypes."""
310  _uuid_generate_time(_buffer)
311  return UUID(bytes=_buffer.raw).node
312 
314  """Get the hardware address on Windows using ctypes."""
315  if _UuidCreate(_buffer) == 0:
316  return UUID(bytes=_buffer.raw).node
317 
319  """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
320  import random
321  return random.randrange(0, 1<<48L) | 0x010000000000L
322 
323 _node = None
324 
325 def getnode():
326  """Get the hardware address as a 48-bit integer. The first time this
327  runs, it may launch a separate program, which could be quite slow. If
328  all attempts to obtain the hardware address fail, we choose a random
329  48-bit number with its eighth bit set to 1 as recommended in RFC 4122."""
330 
331  global _node
332  if _node:
333  return _node
334 
335  import sys
336  if sys.platform == 'win32':
337  getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
338  else:
339  getters = [_unixdll_getnode, _ifconfig_getnode]
340 
341  for getter in getters + [_random_getnode]:
342  try:
343  _node = getter()
344  except:
345  continue
346  if _node:
347  return _node
348 
349 def uuid1(node=None, clock_seq=None):
350  """Generate a UUID from a host ID, sequence number, and the current time.
351  If 'node' is not given, getnode() is used to obtain the hardware
352  address. If 'clock_seq' is given, it is used as the sequence number;
353  otherwise a random 14-bit sequence number is chosen."""
354 
355  # When the system provides a version-1 UUID generator, use it (but don't
356  # use UuidCreate here because its UUIDs don't conform to RFC 4122).
357  if _uuid_generate_time and node is clock_seq is None:
358  _uuid_generate_time(_buffer)
359  return UUID(bytes=_buffer.raw)
360 
361  import time
362  nanoseconds = int(time.time() * 1e9)
363  # 0x01b21dd213814000 is the number of 100-ns intervals between the
364  # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
365  timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
366  if clock_seq is None:
367  import random
368  clock_seq = random.randrange(1<<14L) # instead of stable storage
369  time_low = timestamp & 0xffffffffL
370  time_mid = (timestamp >> 32L) & 0xffffL
371  time_hi_version = (timestamp >> 48L) & 0x0fffL
372  clock_seq_low = clock_seq & 0xffL
373  clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL
374  if node is None:
375  node = getnode()
376  return UUID(fields=(time_low, time_mid, time_hi_version,
377  clock_seq_hi_variant, clock_seq_low, node), version=1)
378 
379 def uuid3(namespace, name):
380  """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
381  import md5
382  hash = md5.md5(namespace.bytes + name).digest()
383  return UUID(bytes=hash[:16], version=3)
384 
385 def uuid4():
386  """Generate a random UUID."""
387 
388  # When the system provides a version-4 UUID generator, use it.
389  if _uuid_generate_random:
390  _uuid_generate_random(_buffer)
391  return UUID(bytes=_buffer.raw)
392 
393  # Otherwise, get randomness from urandom or the 'random' module.
394  try:
395  import os
396  return UUID(bytes=os.urandom(16), version=4)
397  except:
398  import random
399  bytes = [chr(random.randrange(256)) for i in range(16)]
400  return UUID(bytes=bytes, version=4)
401 
402 def uuid5(namespace, name):
403  """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
404  import sha
405  hash = sha.sha(namespace.bytes + name).digest()
406  return UUID(bytes=hash[:16], version=5)
407 
408 # The following standard UUIDs are for use with uuid3() or uuid5().
409 
410 NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
411 NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
412 NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
413 NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')
def __cmp__(self, other)
def __init__(self, hex=None, bytes=None, fields=None, int=None, version=None)
def split(input, delimiter)
Split string by delimiter.
Definition: StringUtil.py:323
def uuid1(node=None, clock_seq=None)
def uuid3(namespace, name)
def __setattr__(self, name, value)
def uuid5(namespace, name)


openrtm_aist_python
Author(s): Shinji Kurihara
autogenerated on Thu Jun 6 2019 19:11:35