[python] 파이썬에서 uuid.uuid1 () 대 uuid.uuid4 ()를 언제 사용해야합니까?

문서와 의 차이점을 이해합니다 .

uuid1():
호스트 ID, 시퀀스 번호 및 현재 시간에서 UUID 생성

uuid4():
임의의 UUID를 생성합니다.

따라서 uuid1기계 / 시퀀스 / 시간 정보를 사용하여 UUID를 생성합니다. 각각을 사용하는 장단점은 무엇입니까?

uuid1()기계 정보를 기반으로하므로 개인 정보 보호 문제 가 발생할 수 있음을 알고 있습니다. 하나를 선택할 때 더 미묘한 지 궁금합니다. 나는 uuid4()완전히 임의의 UUID이기 때문에 지금 당장 사용 합니다. 그러나 uuid1충돌의 위험을 줄이기 위해 사용해야하는지 궁금합니다 .

기본적으로, 나는 하나를 사용하는 것에 대한 모범 사례에 대한 사람들의 팁을 찾고 있습니다. 감사!



답변

uuid1()충돌이 발생하지 않도록 보장합니다 (동시에 너무 많은 충돌을 생성하지 않는다는 가정하에). uuidmac 주소가 컴퓨터 전체에서 고유하게 사용되기 때문에 컴퓨터와 컴퓨터 사이에 연결이없는 것이 중요하다면 사용하지 않을 것 입니다.

100ns 미만에서 2 14 uuid1 이상을 생성하여 복제본을 생성 할 수 있지만 대부분의 사용 사례에서는 문제가되지 않습니다.

uuid4()말했듯이 임의의 UUID를 생성합니다. 충돌의 가능성은 정말로, 정말로, 정말로 작습니다. 충분히 작아서 걱정하지 않아도됩니다. 문제는 난수 생성기가 잘못되면 충돌 가능성이 높아진다는 것입니다.

Bob Aman의 훌륭한 답변은 그것을 훌륭하게 요약합니다. (전체 답변을 읽는 것이 좋습니다.)

솔직히 악의적 인 행위자가없는 단일 응용 프로그램 공간에서 초당 4 UUID를 생성하더라도 버전 4 UUID에서도 충돌이 발생하기 훨씬 전에 지구상의 모든 생명이 멸종됩니다.


답변

당신이 고려할 수 있습니다 하나 개의 인스턴스 uuid1()가 아닌이 uuid4()있다 UUID를 별도의 시스템에서 발생하는 경우 다수의 온라인 거래를 목적으로 크기 조정을위한 여러 시스템에서 프로세스를 때, 예를 들어,.

이러한 상황에서, 예를 들어 의사 난수 생성기가 초기화되는 방식의 잘못된 선택으로 인해 충돌이 발생할 위험이 있으며, 잠재적으로 더 많은 수의 UUID가 생성되면 중복 ID를 생성 할 가능성이 높아집니다.

이 경우의 또 다른 관심은 uuid1()각 GUID가 처음 생성 된 시스템이 암시 적으로 (UUID의 “노드”부분에) 기록된다는 것입니다. 이것과 시간 정보는 디버깅에만 도움이 될 수 있습니다.


답변

우리 팀은 데이터베이스 업그레이드 스크립트를 위해 UUID1을 사용하는 데 어려움을 겪었습니다. 데이터베이스 업그레이드 스크립트는 몇 분 안에 ~ 120k UUID를 생성했습니다. UUID 충돌로 인해 기본 키 제약 조건이 위반되었습니다.

100 대의 서버를 업그레이드했지만 Amazon EC2 인스턴스에서이 문제가 몇 차례 발생했습니다. 시계 해상도가 좋지 않고 UUID4로 전환하면 문제가 해결 된 것 같습니다.


답변

사용할 때주의 할 점은 uuid1당신이 (주지 않고 기본 호출을 사용하는 경우, clock_seq당신이 충돌로 실행의 기회가 매개 변수) : 당신은 임의성의 14 비트가을 (100ns의 내 18 개 항목을 생성하는 당신에게 충돌 참조의 약 1 %의 기회를 제공합니다 생일 역설 / 공격). 대부분의 사용 사례에서는이 문제가 발생하지 않지만 클럭 해상도가 낮은 가상 시스템에서는 문제가 발생할 수 있습니다.


답변

아마도 언급되지 않은 것은 지방의 것입니다.

MAC 주소 또는 시간 기반 순서 (UUID1)는 무작위로 분산 된 것 (UUID4)보다 숫자를 더 가깝게 정렬하는 작업이 적기 때문에 데이터베이스 성능을 향상시킬 수 있습니다 ( 여기 참조 ).

두 번째 관련 문제는 원본 데이터가 손실되거나 명시 적으로 저장되지 않은 경우에도 UUID1을 사용하는 것이 디버깅에 유용 할 수 있다는 것입니다.


답변

허용되는 답변 외에도 경우에 따라 유용 할 수있는 세 번째 옵션이 있습니다.

임의의 MAC이있는 v1 ( “v1mc”)

임의의 브로드 캐스트 MAC 주소를 사용하여 의도적으로 v1 UUID를 생성하여 v1과 v4간에 하이브리드를 만들 수 있습니다 (v1 사양에서 허용됨). 결과 v1 UUID는 시간에 따라 다르지만 (일반 v1과 같지만) v4와 같은 모든 호스트 관련 정보가 없습니다. v1mc = 60 비트 시간 + 61 개의 랜덤 비트 = 121 개의 고유 비트; v4 = 122 개의 랜덤 비트.

처음에 이것이 Postgres의 uuid_generate_v1mc () 함수였습니다. 그 후 다음과 같은 파이썬을 사용했습니다.

from os import urandom
from uuid import uuid1
_int_from_bytes = int.from_bytes  # py3 only

def uuid1mc():
    # NOTE: The constant here is required by the UUIDv1 spec...
    return uuid1(_int_from_bytes(urandom(6), "big") | 0x010000000000)

(참고 : UUID 객체를 직접 만드는 더 길고 빠른 버전이 있습니다. 원하는 경우 게시 할 수 있습니다)


대량의 호출 / 초의 경우 시스템 임의성이 소진 될 가능성이 있습니다. 당신은 할 수 다음 stdlib 사용 random(아마도 빨라집니다) 대신 모듈. 그러나 경고 : 공격자가 RNG 상태를 파악하여 향후 UUID를 부분적으로 예측하려면 수백 개의 UUID 만 있으면됩니다.

import random
from uuid import uuid1

def uuid1mc_insecure():
    return uuid1(random.getrandbits(48) | 0x010000000000)


답변