root/gaphor/tags/gaphor-0.12.0/gaphor/misc/uniqueid.py

Revision 924, 4.7 kB (checked in by arjanmol, 3 years ago)

--

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 import copy
2 import inspect
3 import types
4 import string
5 import random
6 import time
7 import os
8 import sys
9
10 # This module is taken from SMW
11
12 def __getHundredNanosecondsSinceGregorianReform__():
13     """<<<The timestamp is a 60 bit value. For UUID version 1, this is
14     represented by Coordinated Universal Time (UTC) as a count of
15     100-nanosecond intervals since 00:00:00.00, 15 October 1582 (the
16     date of Gregorian reform to the Christian calendar).>>>"""
17
18     # Since 1.1.1970 (unix epoch time)
19     # BUG probably platform-dependent
20     ns = time.time() * 1000 * 1000 * 10
21
22     # Amount of 100 nanoseconds between 15.Oct.1582 to 1.1.1970
23     # Takes even leap years into account
24     ns_greg = ((1970-1583) * 365 + 78 + 92) * 24 * 60 * 60 * 1000 * 1000 * 10
25
26     # BUG can long conversion lose information?
27     return long(ns) + ns_greg
28
29 #Place holder for a RNG
30 theRNG=None
31
32 # Our NIC's MAC
33 ethernet = ""
34 # Our clocksequence
35 clocksequence = None
36 # Latest UTC
37 latest_utc = 0
38
39 def __generateString__(value, n_nibbles):
40     """Generates nibbles, and reverses the resulting string."""
41     s = []
42     for i in range(n_nibbles):
43         digit = value & 15
44         value //= 16
45         s.append(string.hexdigits[digit])
46
47     s.reverse()
48     return string.join(s, "")
49    
50
51 def __generateID__():
52     """This function returns a string with a unique ID for XMI objects.
53     It adheres to the DCE specification of generating globally
54     unique id:s. Assume there are buglets in this implementation,
55     the spec isn't _that_ clean on the matter.
56     http://www.opengroup.org/onlinepubs/9629399/apdxa.htm
57     """
58    
59     global theRNG
60     global ethernet
61     global clocksequence
62     global latest_utc
63
64     if not theRNG:
65         theRNG = random.Random(time.time())
66         # Get the ethernet address
67         try:
68             if sys.platform.find('linux') >= 0:
69                 #
70                 # RedHat Linux, Debian GNU/Linux, SunOS 2.6
71                 #
72                 f = os.popen("/sbin/ifconfig -a")
73                 while 1:
74                     s = f.readline()
75                     if not s:
76                         raise Exception
77
78                     i = s.find("HWaddr")
79                     if i != -1:
80                         ethernet = string.join(s[i:].split()[1].split(":"), "")
81                         f.close()
82                         break;
83             elif sys.platform.find('darwin') >= 0 \
84                  or sys.platform.find('sun') >= 0:
85                 #
86                 # Darwin (Mac OS X) and SunOS
87                 #
88                 f = os.popen("/sbin/ifconfig -a")
89                 while 1:
90                     s = f.readline()
91                     if not s:
92                         raise Exception
93                     i = s.find("ether")
94                     if i != -1:
95                         e = s[i:].split()[1].split(":")
96                         for i in range(len(e)):
97                             if len(e[i]) == 1:
98                                 e[i] = "0" + e[i]
99                         ethernet = string.join(e, "")
100                         f.close()
101                         break
102             elif sys.platform.find('win') >= 0:
103                 #
104                 # Windows 2000 (perhaps also NT and XP)
105                 #
106                 f = os.popen("ipconfig /all")
107                 while 1:
108                     s = f.readline()
109                     if not s:
110                         raise Exception
111                    
112                     i = s.find("Physical Address")
113                     if i != -1:
114                         i = s.find(":")
115                         if i != -1:
116                             ethernet = string.join(s[i:].split()[1].split("-"), "")
117                         f.close()
118                         break
119         except:
120             # BUG: We randomize
121             e = []
122             for eth_i in range(12):
123                 e.append(string.hexdigits[theRNG.randrange(16)])
124             ethernet = string.join(e, "")
125
126         # Initialize clock sequence. 14 bits
127         clocksequence = theRNG.randrange(16384)
128        
129     s = ""
130     # the final DCE string is of the form
131     # "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
132     value = __getHundredNanosecondsSinceGregorianReform__()
133     index = 0
134
135     if value <= latest_utc:
136         clocksequence += 1
137     else:
138         latest_utc = value
139
140     # time_low
141     s += __generateString__(value, 8)
142     s += "-"
143    
144     # time_mid
145     value >>= (4*8)
146     s += __generateString__(value, 4)
147     s += "-"
148     value >>= (4*4)
149
150     # time_hi_and_version
151     value |= 1<<12 # UUID version 1
152     s += __generateString__(value, 4)
153     s += "-"
154
155     value = clocksequence
156     value |= 1<<15 # DCE variant
157     s += __generateString__(value, 4)
158     s += "-"
159
160     s += ethernet
161
162     return "DCE:%s" % s.upper()
163
164 def generate_id():
165     return __generateID__()
Note: See TracBrowser for help on using the browser.