Quale versione UUID usare?


332

Quale versione dell'UUID dovresti usare? Ho visto molti thread che spiegano cosa comporta ciascuna versione, ma ho difficoltà a capire quale sia la soluzione migliore per quali applicazioni.


2
Quali sono le tue scelte?
Gabe,

Tutto ciò che funziona con Python. Quindi immagino che questo docs.python.org/2/library/uuid.html . 1,3,4,5.
user1802143

Se sei curioso di conoscere le versioni 3 e 5, vedi questa domanda, Generazione dell'UUID v5. Che cos'è il nome e lo spazio dei nomi? .
Basil Bourque,

Risposte:


414

Esistono due modi diversi per generare un UUID.

Se hai solo bisogno di un ID univoco, vuoi una versione 1 o versione 4.

  • Versione 1: genera un ID univoco basato su un indirizzo MAC della scheda di rete e un timer. Questi ID sono facili da prevedere (se ne avessi uno, potrei essere in grado di indovinarne un altro) e possono essere ricondotti alla tua scheda di rete. Non è consigliabile crearli.

  • Versione 4: sono generati da numeri casuali (o pseudo-casuali). Se hai solo bisogno di generare un UUID, questo è probabilmente quello che vuoi.

Se è necessario generare sempre lo stesso UUID da un determinato nome, si desidera una versione 3 o 5.

  • Versione 3: questo genera un ID univoco da un hash MD5 di uno spazio dei nomi e un nome. Se hai bisogno di retrocompatibilità (con un altro sistema che genera UUID dai nomi), usa questo.

  • Versione 5: questo genera un ID univoco da un hash SHA-1 di uno spazio dei nomi e un nome. Questa è la versione preferita.


17
Vorrei aggiungere: se è necessario generare un reproducibleUUID da un determinato nome, si desidera una versione 3 o versione 5. Se si alimenta l'algoritmo con lo stesso input, genererà lo stesso output.
anregen,

3
In un ambiente di cloud computing (come AWS o GAE), sembrerebbe che la debolezza della versione 1 sia mitigata nell'oblio. Dove è probabile che ci siano migliaia di indirizzi MAC diversi applicati al generatore UUID di una determinata applicazione nel tempo, eliminando prevedibilità e / o tracciabilità.
Buffalo Rabor,

3
@ user239558 Dato che l'obiettivo di un UUID è la sua unicità, UUIDv5 può ancora essere preferito.
Epicureo

7
Quel commento sulla versione 1 non è "raccomandato", è eccessivamente semplicistico. In molte situazioni, queste sono davvero belle e preferibili. Ma se hai problemi di sicurezza riguardo alla perdita di uno di questi elementi di informazioni da un UUID che potrebbe essere reso disponibile per attori inaffidabili: (a) l'indirizzo MAC della macchina che crea l'UUID o (b) la data e l'ora in cui viene creato, quindi evita la versione 1. Se queste due informazioni non sono sensibili, la versione 1 è un ottimo modo per procedere.
Basil Bourque,

9
Che cosa è successo alla versione 2?
Matthew Woo,

53

Se si desidera un numero casuale, utilizzare una libreria di numeri casuali. Se vuoi un identificatore univoco con efficacemente 0,00 ... molti più 0 qui ... 001% di possibilità di collisione, dovresti usare UUIDv1. Vedi il post di Nick per UUIDv3 e v5.

UUIDv1 NON è sicuro. Non è pensato per essere. È pensato per essere UNICO, non indovinabile. UUIDv1 utilizza il timestamp corrente, oltre a un identificatore macchina, oltre ad alcuni elementi casuali per creare un numero che non verrà mai più generato da quell'algoritmo. Questo è appropriato per un ID transazione (anche se tutti fanno milioni di transazioni).

Ad essere sincero, non capisco perché UUIDv4 esista ... dalla lettura di RFC4122 , sembra che quella versione NON elimini la possibilità di collisioni. È solo un generatore di numeri casuali. Se questo è vero, allora hai una BUONA possibilità di due macchine nel mondo che alla fine creano lo stesso "UUID" v4 (virgolette perché non esiste un meccanismo per garantire U.niversal U.niqueness). In quella situazione, non penso che l'algoritmo appartenga a un RFC che descriva metodi per generare valori univoci. Apparterrebbe a un RFC sulla generazione di casualità. Per un set di numeri casuali:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)

67
Non vedrai scontrarsi due implementazioni UUID versione 4, a meno che non generi un miliardo di UUID ogni secondo per un secolo e vinci un lancio di moneta . Ricorda, set_sizeè 2 ^ 122, che è molto grande .
Kevin,

8
L'algoritmo V4 non è seriale, ciò significa che esiste la possibilità che i primi due UUID generati da v4 possano corrispondere. Solo perché ci sono molte opzioni, non significa che devi rimanere senza opzioni uniche prima di generare una ripetizione. Ciò potrebbe accadere in qualsiasi momento.
anregen,

7
Non stai davvero facendo la matematica. Noi (come specie) non generiamo 1 miliardo di UUID al secondo. Quindi abbiamo più di 100 anni fino alla prima collisione (in media).
Kevin,

31
V4 "potrebbe" scontrarsi, ma la probabilità è eccezionalmente bassa che per la maggior parte dei casi d'uso vale il rischio. Ri: "due macchine nel mondo alla fine creano lo stesso 'UUID'v4", beh, certo, ma questo non è un problema perché la maggior parte delle macchine nel mondo che usano UUID li usano in contesti diversi. Voglio dire, se creo lo stesso UUID per la mia app interna come lo fai per la tua app interna, allora non importa. Le collisioni contano solo se si verificano nello stesso contesto. (ricorda, anche all'interno di un'app, molti UUID non devono essere univoci nell'intera app, solo il contesto in cui sono utilizzati)

6
Quindi sembra che, se non hai bisogno del tuo Guid per essere sicuro, usa la versione 1. Se ti serve sicuro e ti senti fortunato (o davvero, non sentirti sfortunato) usa la versione 4.
Vaccano

16

Questa è una domanda molto generale. Una risposta è: "dipende dal tipo di UUID che desideri generare". Ma uno migliore è questo: "Bene, prima di rispondere, puoi dirci perché è necessario codificare il proprio algoritmo di generazione UUID invece di chiamare la funzionalità di generazione UUID fornita dalla maggior parte dei moderni sistemi operativi?"

Fare ciò è più semplice e sicuro e, poiché probabilmente non è necessario generare il proprio, perché preoccuparsi di codificare un'implementazione? In tal caso, la risposta diventa uso qualunque sia il tuo O / S, linguaggio di programmazione o framework. Ad esempio, in Windows è disponibile CoCreateGuid o UuidCreate o uno dei vari wrapper disponibili nei numerosi framework in uso. In Linux c'è uuid_generate .

Se, per qualche motivo, devi assolutamente generare il tuo, allora almeno hai il buon senso di stare lontano dalla generazione di UUID v1 e v2. È difficile ottenere quelli giusti. Attenersi, invece, agli UUID v3, v4 o v5.

Aggiornamento : in un commento, dici che stai usando Python e link a questo . Guardando attraverso l'interfaccia fornita, l' opzione più semplice per te sarebbe quella di generare un UUID v4 (cioè uno creato da dati casuali) chiamando uuid.uuid4().

Se si dispone di alcuni dati di cui è necessario (o possibile) eseguire l'hash per generare un UUID, è possibile utilizzare v3 (che si basa su MD5) o v5 (che si basa su SHA1). Generare un UUID v3 o v5 è semplice: prima seleziona il tipo di UUID che desideri generare (dovresti probabilmente scegliere la v5), quindi scegli lo spazio dei nomi appropriato e chiama la funzione con i dati che desideri utilizzare per generare l'UUID. Ad esempio, se si esegue l'hashing di un URL, utilizzare NAMESPACE_URL:

uuid.uuid3(uuid.NAMESPACE_URL, 'https://ripple.com')

Si noti che questo UUID sarà diverso dall'UUID v5 per lo stesso URL, generato in questo modo:

uuid.uuid5(uuid.NAMESPACE_URL, 'https://ripple.com')

Una bella proprietà degli URL v3 e v5 è che dovrebbero essere interoperabili tra le implementazioni. In altre parole, se due sistemi diversi utilizzano un'implementazione conforme a RFC4122, genereranno (o almeno dovrebbero ) entrambi generano lo stesso UUID se tutte le altre cose sono uguali (ovvero generano lo stesso UUID versione, con lo stesso spazio dei nomi e il stessi dati). Questa proprietà può essere molto utile in alcune situazioni (specialmente in scenari di archiviazione indirizzabili al contenuto), ma forse non nel tuo caso particolare.


4
Immagino che sia perché OP non ha chiesto: come faccio a "codificare [il mio] algoritmo di generazione UUID invece di chiamare la funzionalità di generazione UUID fornita dalla maggior parte dei sistemi operativi moderni?"
anregen,

A parte questo, penso che sia una buona spiegazione di UUIDv3 e v5. Vedi la mia risposta di seguito sul perché penso che v1 possa essere una buona scelta.
anregen,

che cos'è NAMESPACE_URL? è una variabile che posso ottenere? da dove?
stackdave,

@stackdave NAMESPACE_URLè un UUID generalmente uguale a 6ba7b811-9dad-11d1-80b4-00c04fd430c8, seguendo la raccomandazione fatta a pagina 30 di RFC-4122 .
Jamie Ridding,

2

La documentazione di Postgres descrive le differenze tra UUIDs. Un paio di loro:

V3:

uuid_generate_v3(namespace uuid, name text) - Questa funzione genera un UUID versione 3 nello spazio dei nomi indicato utilizzando il nome di input specificato.

V4:

uuid_generate_v4 - Questa funzione genera un UUID versione 4, che deriva interamente da numeri casuali.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.