lib python random unique-id

uuid lib python



¿Cómo puedo generar una identificación única en Python? (9)

Esta pregunta ya tiene una respuesta aquí:

Necesito generar una identificación única basada en un valor aleatorio.


¿Tal vez el módulo uuid ?


único y aleatorio son mutuamente excluyentes. tal vez quieres esto?

import random def uniqueid(): seed = random.getrandbits(32) while True: yield seed seed += 1

Uso:

unique_sequence = uniqueid() id1 = next(unique_sequence) id2 = next(unique_sequence) id3 = next(unique_sequence) ids = list(itertools.islice(unique_sequence, 1000))

no hay dos ID devueltos es el mismo (Único) y esto se basa en un valor de inicialización aleatorio


Es posible que desee funciones de UUID de Python:

uuid uuid

p.ej:

import uuid print uuid.uuid4()

7d529dd4-548b-4258-aa8e-23e34dc8d43d


Esto funcionará muy rápido pero no generará valores aleatorios sino que aumentará monótonamente (para un hilo dado).

import threading _uid = threading.local() def genuid(): if getattr(_uid, "uid", None) is None: _uid.tid = threading.current_thread().ident _uid.uid = 0 _uid.uid += 1 return (_uid.tid, _uid.uid)

Es seguro para subprocesos y trabajar con tuplas puede tener beneficios en lugar de cadenas (más corto, en todo caso). Si no necesita seguridad de hilo, siéntase libre de quitar las brocas de roscar (en lugar de roscar.local , use object () y quite el tid por completo).

Espero que ayude.


Quizás uuid.uuid4() podría hacer el trabajo. Ver uuid para más información.


Tal vez este trabajo para ti

str(uuid.uuid4().fields[-1])[:5]


aquí puedes encontrar una implementación:

def __uniqueid__(): """ generate unique id with length 17 to 21. ensure uniqueness even with daylight savings events (clocks adjusted one-hour backward). if you generate 1 million ids per second during 100 years, you will generate 2*25 (approx sec per year) * 10**6 (1 million id per sec) * 100 (years) = 5 * 10**9 unique ids. with 17 digits (radix 16) id, you can represent 16**17 = 295147905179352825856 ids (around 2.9 * 10**20). In fact, as we need far less than that, we agree that the format used to represent id (seed + timestamp reversed) do not cover all numbers that could be represented with 35 digits (radix 16). if you generate 1 million id per second with this algorithm, it will increase the seed by less than 2**12 per hour so if a DST occurs and backward one hour, we need to ensure to generate unique id for twice times for the same period. the seed must be at least 1 to 2**13 range. if we want to ensure uniqueness for two hours (100% contingency), we need a seed for 1 to 2**14 range. that''s what we have with this algorithm. You have to increment seed_range_bits if you move your machine by airplane to another time zone or if you have a glucky wallet and use a computer that can generate more than 1 million ids per second. one word about predictability : This algorithm is absolutely NOT designed to generate unpredictable unique id. you can add a sha-1 or sha-256 digest step at the end of this algorithm but you will loose uniqueness and enter to collision probability world. hash algorithms ensure that for same id generated here, you will have the same hash but for two differents id (a pair of ids), it is possible to have the same hash with a very little probability. You would certainly take an option on a bijective function that maps 35 digits (or more) number to 35 digits (or more) number based on cipher block and secret key. read paper on breaking PRNG algorithms in order to be convinced that problems could occur as soon as you use random library :) 1 million id per second ?... on a Intel(R) Core(TM)2 CPU 6400 @ 2.13GHz, you get : >>> timeit.timeit(uniqueid,number=40000) 1.0114529132843018 an average of 40000 id/second """ mynow=datetime.now sft=datetime.strftime # store old datetime each time in order to check if we generate during same microsecond (glucky wallet !) # or if daylight savings event occurs (when clocks are adjusted backward) [rarely detected at this level] old_time=mynow() # fake init - on very speed machine it could increase your seed to seed + 1... but we have our contingency :) # manage seed seed_range_bits=14 # max range for seed seed_max_value=2**seed_range_bits - 1 # seed could not exceed 2**nbbits - 1 # get random seed seed=random.getrandbits(seed_range_bits) current_seed=str(seed) # producing new ids while True: # get current time current_time=mynow() if current_time <= old_time: # previous id generated in the same microsecond or Daylight saving time event occurs (when clocks are adjusted backward) seed = max(1,(seed + 1) % seed_max_value) current_seed=str(seed) # generate new id (concatenate seed and timestamp as numbers) #newid=hex(int(''''.join([sft(current_time,''%f%S%M%H%d%m%Y''),current_seed])))[2:-1] newid=int(''''.join([sft(current_time,''%f%S%M%H%d%m%Y''),current_seed])) # save current time old_time=current_time # return a new id yield newid """ you get a new id for each call of uniqueid() """ uniqueid=__uniqueid__().next import unittest class UniqueIdTest(unittest.TestCase): def testGen(self): for _ in range(3): m=[uniqueid() for _ in range(10)] self.assertEqual(len(m),len(set(m)),"duplicates found !")

Espero eso ayude !


import time def new_id(): time.sleep(0.000001) return time.time()

En mi sistema, time.time () parece ofrecer 6 cifras significativas después del punto decimal. Con un sueño breve, debe garantizarse que sea único con al menos una cantidad moderada de aleatoriedad en los últimos dos o tres dígitos.

Podrías hacer hash también si estás preocupado.


import time import random import socket import hashlib 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