[Python-Dev] UUID module
Thomas Heller
theller at python.net
Sat Jun 10 17:11:15 CEST 2006
Ka-Ping Yee wrote:
> Finally, Phillip brought up PEAK:
>> PEAK's uuid module does this such that if win32all is present,
>> you get a Windows GUID, or if you have a FreeBSD 5+ or
>> NetBSD 2+ kernel you use the local platform uuidgen API. See e.g.:
>
> ...so i looked at PEAK's getnodeid48() routine and borrowed the
> Win32 calls from there, with a comment giving attribution to PEAK.
>
> Oh, and there is now a test suite that should cover all the code paths.
>
> This is all posted at http://zesty.ca/python/uuid.py now,
> documentation page at http://zesty.ca/python/uuid.html,
> tests at http://zesty.ca/python/test_uuid.py .
(From http://zesty.ca/python/uuid.py:)
def win32_getnode():
"""Get the hardware address on Windows using Win32 extensions."""
try:
import pywintypes
return int(pywintypes.CreateGuid()[-13:-1], 16)
except:
pass
try:
import pythoncom
return int(pythoncom.CreateGuid()[-13:-1], 16)
except:
pass
This does not work, for several reasons.
1. (pythoncom|pywintypes).CreateGuid() return a PyIID instance, which you cannot slice:
>>> import pywintypes
>>> pywintypes.CreateGuid()
IID('{4589E547-4CB5-4BCC-A7C3-6E88FAFB4301}')
>>> type(pywintypes.CreateGuid())
<type 'PyIID'>
>>> pywintypes.CreateGuid()[-13:-1]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsubscriptable object
>>>
So, you would have to change your code to 'str(pythoncom.CreateGuid())[-13:-1]'.
(BTW: Why does it first try pywintypes, the pythoncom?)
2. These functions call to win32 CoCreateGuid function, which create a new uuid.
As documented on MSDN, this calls the UuidCreate function which:
"The UuidCreate function generates a UUID that cannot be traced to the ethernet/token ring
address of the computer on which it was generated."
In other words, the last 12 characters do *not* identify the mac address, in fact your function,
if repaired, returns a different result each time it is called. See this link for
further info:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidcreate.asp
A possible solution, if you really need the mac address, is to call the UuidCreateSequential
function where available (W2k, XP, ...), and UuidCreate on older systems (W98, ME).
Link to MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidcreatesequential.asp
3. Now that ctypes is part of Python, why not use it? This snippet of code
displays the mac address of one of the ethernet adapters I have in my machine:
from ctypes import *
import binascii
class UUID(Structure):
_fields_ = [("Data1", c_ulong),
("Data1", c_ushort),
("Data1", c_ushort),
("Data1", c_ubyte * 8)]
def CreateGuid():
uuid = UUID()
if 0 == windll.rpcrt4.UuidCreateSequential(byref(uuid)):
return str(buffer(uuid))
print binascii.hexlify(CreateGuid()[-6:])
It should be extended to also work on w98 or me, probably.
Thomas
More information about the Python-Dev
mailing list