반응형
파이썬에서 고유 ID를 생성하려면 어떻게 해야 합니까?
임의의 값을 기준으로 고유 ID를 생성해야 합니다.
아마uuid.uuid4()그 일을 할 수도 있습니다.자세한 내용은 UUID를 참조하십시오.
Python의 UUID 함수는 다음과 같습니다.
21.15. uuid — RFC 4122에 따른 UUID 개체
예:
import uuid
print uuid.uuid4()
7d529dd4-548b-4258-aa8e-23e34dc8d43d
고유 및 랜덤은 상호 배타적입니다.아마도 당신은 이것을 원합니까?
import random
def uniqueid():
seed = random.getrandbits(32)
while True:
yield seed
seed += 1
용도:
unique_sequence = uniqueid()
id1 = next(unique_sequence)
id2 = next(unique_sequence)
id3 = next(unique_sequence)
ids = list(itertools.islice(unique_sequence, 1000))
반환된 두 ID가 동일하지 않습니다(고유). 이 ID는 무작위 시드 값을 기반으로 합니다.
어쩌면 이 일은 당신을 위한 것입니다.
str(uuid.uuid4().fields[-1])[:5]
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
여기에서 구현을 찾을 수 있습니다.
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 !")
도움이 되길 바랍니다!
이것은 매우 빠르게 작동하지만 랜덤 값을 생성하지 않고 (특정 스레드에 대해) 단조롭게 증가시킵니다.
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)
나사산이 안전하고 튜플로 작업하면 줄에 비해 이점이 있을 수 있습니다(짧은 경우).스레드 안전이 필요하지 않으면 스레드 비트를 자유롭게 제거합니다(threading.local 대신 object()를 사용하고 tid를 모두 제거합니다).
도움이 되길 바랍니다.
UUID 모듈일 수도 있어요?
언급URL : https://stackoverflow.com/questions/1210458/how-can-i-generate-a-unique-id-in-python
반응형
'programing' 카테고리의 다른 글
| 오류: Gdal이 설치되어 있지만 R 종속 패키지를 설치하는 동안 gdal-config를 찾을 수 없습니다. (0) | 2023.06.06 |
|---|---|
| 가져오기를 모의 실행하는 방법 (0) | 2023.06.06 |
| Web.config 변환 옵션이 회색으로 표시됨 (0) | 2023.06.06 |
| require()와 library()의 차이점은 무엇입니까? (0) | 2023.06.06 |
| iOS 및 Firebase 충돌 분석 (0) | 2023.06.06 |