Generatore di UUID
Genera UUID — v4 casuali o v7 ordinati nel tempo — singolarmente o a lotti.
122 bit casuali. Non rivela nulla su quando è stato creato.
Generazione…
Che cos’è un UUID e perché esiste
Un UUID — Universally Unique Identifier, chiamato GUID nella documentazione Microsoft — è un valore da 128 bit scritto come 32 cifre esadecimali nel familiare raggruppamento 8-4-4-4-12. Il suo scopo è permettere a sistemi distinti di coniare identificatori in modo indipendente, senza alcun coordinamento, restando comunque ragionevolmente certi che i risultati non collideranno. È questo a distinguerlo da una colonna auto-incrementale: due server, due client mobili offline su un aereo e un processo in background possono creare record nello stesso istante senza chiedere il permesso a nessuno.
L’unicità qui è probabilistica, non garantita. La versione 4 lascia 122 bit alla casualità, uno spazio abbastanza ampio perché, anche generando miliardi di valori, la probabilità di una ripetizione resti molto al di sotto di quella che un disco corrompa i dati in silenzio. In pratica puoi trattarlo come unico: la matematica non è l’anello debole.
Versione 4 contro versione 7: la scelta che conta
La versione 4 è casuale da cima a fondo. Non trasporta alcuna informazione: né quando è stata creata, né da chi, né in quale ordine. È il suo pregio maggiore o il suo difetto centrale, a seconda di dove la collochi.
La versione 7, standardizzata nell’RFC 9562 nel 2024, sostituisce i primi 48 bit con un timestamp Unix in millisecondi e riempie il resto di casualità. Poiché il tempo viene per primo e il valore si legge da sinistra a destra, ordinare identificatori v7 come semplice testo li ordina anche cronologicamente.
Non è una differenza estetica. I database tengono le chiavi primarie in un indice B-tree ordinato. Inserisci chiavi v7 e ogni nuova riga atterra sul bordo destro dell’albero, accanto alla precedente: le pagine su cui scrivi restano in memoria e l’indice cresce ordinato. Inserisci chiavi v4 e ogni scrittura cade in una posizione casuale, il database tocca ogni volta una pagina diversa, il tasso di successo della cache cala e l’indice si frammenta. Su una tabella grande e trafficata la differenza di throughput in inserimento è notevole, ed è per questo che v7 è stato adottato così rapidamente per le chiavi primarie.
- Scegli v7 per chiavi primarie, identificatori di eventi e log, e tutto ciò che vorrai ordinare o interrogare per intervallo di data di creazione.
- Scegli v4 quando l’identificatore compare in un contesto non fidato e non deve trapelare nulla — nemmeno che un record è stato creato appena prima di un altro.
- Entrambi vanno bene per un ID di correlazione, una chiave di idempotenza o un nome di file, dove l’ordine non conta.
Il compromesso è esattamente quella fuga di informazione: un identificatore v7 dice a chiunque lo veda, al millisecondo, quando è stato creato. Per l’ID di una riga è di solito innocuo e spesso utile. Per un token di reimpostazione password o un link di condivisione pubblico è un’informazione che non intendevi pubblicare — e quelli non dovrebbero essere UUID affatto, ma token casuali da un generatore di segreti dedicato.
L’ordine all’interno dello stesso millisecondo
Una sottigliezza che coglie in fallo molte implementazioni di v7: l’hardware moderno genera ben più di un identificatore al millisecondo. Se due valori condividono il timestamp, il loro ordine è deciso dai bit casuali che seguono, cioè a caso. Generane cinquanta in un ciclo stretto e otterrai cinquanta valori solo approssimativamente ordinati, perdendo proprio la proprietà per cui hai scelto v7.
L’RFC 9562 risolve la cosa con un contatore monotono, e questo strumento lo implementa: i 12 bit immediatamente successivi al timestamp contano in avanti all’interno di un millisecondo, così un lotto è rigorosamente crescente e non soltanto approssimativo. Se il contatore si riempie — più di 4096 valori nello stesso millisecondo — il generatore prende in prestito il millisecondo successivo anziché azzerarsi ed emettere un valore che si ordini prima del precedente. L’orologio che torna indietro, cosa che accade con le correzioni NTP, è gestito allo stesso modo.
Leggendo un valore v7 da sinistra a destra, prendendo 0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b come esempio:
- 0190a1b2-c3d4 — il timestamp Unix a 48 bit in millisecondi. Venendo per primo, l’ordine del testo è l’ordine del tempo.
- 7 — la cifra di versione, ciò che rende questo valore un v7 e non un v4.
- e5f — il contatore monotono a 12 bit, che si incrementa all’interno di un singolo millisecondo.
- 8 — i bit di variante, fissati dall’RFC 9562 per ogni UUID moderno (sempre 8, 9, a o b).
- a9b-0c1d2e3f4a5b — i restanti 62 bit, puramente casuali.
Memorizzare e usare gli UUID
La forma canonica è minuscola con trattini, e l’RFC 9562 dice che i generatori devono emettere esattamente quella — motivo per cui questo strumento non offre opzioni di formato. Incontrerai comunque altre grafie: maiuscole e tra parentesi graffe negli strumenti Microsoft, e senza trattini dove qualcuno voleva una colonna più corta. Sono gli stessi 128 bit, e i confronti dovrebbero ignorare maiuscole e minuscole.
Dove conta davvero è la memorizzazione. Un UUID occupa 16 byte, ma la sua forma testuale ne occupa 36: memorizzarlo come stringa più che raddoppia lo spazio nella riga e, cosa più importante, in ogni indice che lo include. Usa un tipo nativo dove esiste:
uuid -- PostgreSQL: tipo nativo da 16 byte BINARY(16) -- MySQL: compatto; CHAR(36) spreca 20 byte per riga uniqueidentifier -- SQL Server crypto.randomUUID() // JavaScript: solo v4, richiede un contesto sicuro uuid.uuid4() / uuid7() # Python: v4 nella libreria standard; v7 con una libreria
Un’ultima avvertenza: un UUID identifica, non autorizza. Poiché non sono indovinabili, viene la tentazione di trattare come privato un URL non elencato che ne contiene uno. Ma gli identificatori trapelano — attraverso log, cronologia del browser, header referrer e screenshot — quindi tutto ciò che ha davvero bisogno di protezione richiede comunque un vero controllo dei permessi alle spalle.
Domande frequenti
- Meglio v4 o v7?
- Usa v7 per le chiavi primarie e per tutto ciò che ordinerai per data di creazione: il timestamp iniziale tiene gli inserimenti raggruppati in fondo all’indice invece che sparsi. Usa v4 quando l’identificatore non deve rivelare nulla, nemmeno quando è stato creato.
- Due UUID possono essere uguali?
- È possibile ma incredibilmente improbabile. La versione 4 ha 122 bit casuali, quindi anche dopo miliardi di valori generati la probabilità di collisione resta molto inferiore a quella che la memoria li corrompa in silenzio.
- Che fine hanno fatto le versioni 1, 3 e 5?
- La versione 1 codifica un timestamp e l’indirizzo MAC della macchina, rivelando l’identità dell’hardware e comunque non producibile in un browser. Le versioni 3 e 5 derivano un UUID in modo deterministico da uno spazio dei nomi e un nome, usando MD5 o SHA-1: utile quando lo stesso input deve sempre dare lo stesso identificatore, ma è un lavoro diverso dal generarne uno nuovo.
- Un UUID è abbastanza sicuro come token segreto?
- Un UUID v4 non è indovinabile, ma uno v7 codifica apertamente il proprio istante di creazione, e nessuno dei due è pensato come credenziale. Per reimpostazioni di password, token di sessione o link di condivisione, genera un segreto casuale dedicato e verifica i permessi sul server invece di affidarti alla difficoltà di indovinare l’identificatore.
- Perché il mio lotto di v7 non è perfettamente ordinato in altri strumenti?
- Perché molte implementazioni saltano il contatore monotono. Quando più valori condividono un millisecondo, il loro ordine è lasciato ai bit casuali che seguono. Questo strumento implementa il contatore dell’RFC 9562, quindi un lotto generato qui è rigorosamente crescente.
- Come dovrei memorizzare un UUID in un database?
- In un tipo nativo da 16 byte dove esiste — uuid in PostgreSQL, uniqueidentifier in SQL Server, BINARY(16) in MySQL. Memorizzare invece la forma testuale da 36 caratteri più che raddoppia lo spazio usato nella riga e in ogni indice che include la colonna.
- Vengono generati sui vostri server?
- No. Vengono generati nel tuo browser con crypto.getRandomValues, la sorgente crittografica di casualità della piattaforma — la stessa usata da crypto.randomUUID. Nessun valore viene inviato da nessuna parte, e ricaricare la pagina produce un insieme completamente nuovo.