ActiveState Code

Recipe 213761: Simple Universally Unique ID (UUID or GUID)


This is a short & sweet UUID function. Uniqueness is based on network address, time, and random.

Another good point: does not create a "hot spot" when used in a b-tree (database) index. In other words, if your IDs look something like "abc100" and "abc101" and "abc102"; then they will all hit the same spot of a b-tree index, and cause the index to require frequent reorganization. On the other hand, if your IDs look more like "d29fa" and "67b2c" and "e5d36" (nothing alike); then they will spread out over the index, and your index will require infrequent reorganization.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import time, random, md5

def uuid( *args ):
  """
    Generates a universally unique ID.
    Any arguments only create more randomness.
  """
  t = long( time.time() * 1000 )
  r = long( random.random()*100000000000000000L )
  try:
    a = socket.gethostbyname( socket.gethostname() )
  except:
    # if we can't get a network address, just imagine one
    a = random.random()*100000000000000000L
  data = str(t)+' '+str(r)+' '+str(a)+' '+str(args)
  data = md5.md5(data).hexdigest()
  return data

Discussion

Down side: Not especially fast. I would integrate a similar C or java version of this (without the MD5) into my python code if this is a problem.

Comments

  1. 1. At 5:24 a.m. on 7 aug 2003, Bill Scherer said:

    socket missing... It's a tad faster if actually import socket...

    Beware the blanket exception.

  2. 2. At 11:29 a.m. on 8 aug 2003, Joe Madia said:

    What about compliance with the UUID spec? This algorithm does not appear to generate correct UUIDs. UUIDs are officially and specifically defined as part of the ISO-11578 standard [1]. The WebDAV spec [2] also defines, in section 6.4.1, a safe way to calculate the 'node' data required by the UUID algorithm in situations where a network address is either not available or could be a security risk. I have not seen ISO-11578 but I understand that it is very similar to the algorithm defined in the UUIDs and GUIDs Internet Draft [3] which does not appear to be similar to this code at all.

    Am I missing something obvious here?

    [1] ISO/IEC 11578 - Remote Procedure Call (RPC)

    http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=2229

    [2] HTTP Extensions for Distributed Authoring -- WEBDAV

    http://www.ietf.org/rfc/rfc2518.txt

    [3] UUIDs and GUIDs

    http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt

  3. 3. At 8:24 a.m. on 5 nov 2003, Michael Hoffman said:

    If you are on a UNIX system with the uuidgen command. You can use:

    import commands def uuidgen(): return commands.getoutput('uuidgen')

  4. 4. At 8:25 a.m. on 5 nov 2003, Michael Hoffman said:

    That should be.

    import commands
    def uuidgen():
        return commands.getoutput('uuidgen')
    
  5. 5. At 10:16 a.m. on 4 apr 2007, Jon Marshall said:

    A UUID module is now included in the standard distribution. A uuid module is included in python 2.5+. 2.3 and 2.4 users can get the module from http://zesty.ca/python/

Sign in to comment