I need to generate a unique ID based on a random value.
Watch out, the library underlying that module is buggy and tends to fork a process that keeps FDs open. That's fixed in newer versions, but most people probably don't have that yet, so I generally avoid this module. Caused me major headaches with listen sockets...
Glenn Maynard
2009-07-31 03:14:59
A:
import time
def new_id():
time.sleep(0.000001)
return time.time()
On my system, time.time() seems to offer 6 significant figures after the decimal point. With a brief sleep it should be guaranteed unique with at least a moderate amount of randomness down in the last two or three digits.
You could hash it as well if you're worried.
John Fouhy
2009-07-31 03:55:14
Hashing it won't make it any more unique, and there's a strong chance of a collision eventually if more than one process is doing this--anywhere, not even just on the same machine. This is no way to generate unque IDs.
Glenn Maynard
2009-07-31 04:24:48
Hashing will stop people guessing by incrementing. It'll be unique if there's only one thread handing out IDs, I think. A lot depends on what the IDs are _for_. (and why they have to be both unique and random)
John Fouhy
2009-07-31 05:45:26
A:
unique and random are mutually exclusive. perhaps you want this?
import random
def uniqueid():
seed = random.getrandbits(32)
while True:
yield seed
seed += 1
Usage:
unique_sequence = uniqueid()
id1 = unique_sequence()
id2 = unique_sequence()
id3 = unique_sequence()
ids = [unique_sequence() for dummy in range(1000)]
no two returned id is the same (Unique) and this is based on a randomized seed value
TokenMacGuy
2009-07-31 04:04:30
This isn't unique. If I start it twice, and generate a million values each time, the chances of a collision between the two runs is significant. I'd have to store the last "seed" each time to avoid that--and then there's no point to having the seed; it's just a sequence generator. *Statistically* unique IDs typically are generated from random data; at least one class of UUIDs works that way.
Glenn Maynard
2009-07-31 04:38:01
It is unique so long as each unique sequence comes from only a single invocation of uniqueid. there is no guarantee of uniqueness across generators.
TokenMacGuy
2009-07-31 05:14:03
is there something wrong with generating unique ID's by means of a counter? this is a common practice in databse design.
TokenMacGuy
2009-07-31 17:30:25
A:
def guid( *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 = hashlib.md5(data).hexdigest()
return data
mluebke
2009-07-31 17:50:32