Come testare UUID / GUID validi?


270

Come verificare se la variabile contiene un identificatore UUID / GUID valido?

Al momento sono interessato solo a convalidare i tipi 1 e 4, ma non dovrebbe essere una limitazione alle tue risposte.


in formato stringa, non esadecimale, non bin, o non so che cosa chiedi
Marek Sebera,

^ (\ {) {0,1} [0-9a-fA-F] {8} \ - [0-9a-fA-F] {4} \ - [0-9a-fA-F] {4} \ - [0-9a-fA-F] {4} \ - [0-9a-fA-F] {12} (\}) {0,1} $
Brandon Moretz,

Se non puoi escludere variabili contenenti una catena di 32 cifre esadecimali consecutive (senza raggruppamento), dai un'occhiata alla mia risposta
Lupo

Risposte:


413

Attualmente, gli UUID sono quelli specificati in RFC4122. Un caso limite spesso trascurato è l'UUID NIL, indicato qui . La seguente regex tiene conto di ciò e restituirà una corrispondenza per un UUID NIL. Vedi sotto per un UUID che accetta solo UUID non-NIL. Entrambe queste soluzioni sono per le versioni da 1 a 5 (vedere il primo carattere del terzo blocco).

Pertanto per convalidare un UUID ...

/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i

... garantisce di avere un UUID formattato canonicamente che va dalla versione 1 alla 5 ed è la variante appropriata secondo RFC4122.

NOTA: le parentesi graffe {e }non sono canoniche. Sono un artefatto di alcuni sistemi e usi.

Facile da modificare il regex sopra per soddisfare i requisiti della domanda originale.

SUGGERIMENTO: gruppo regex / acquisizioni

Per evitare la corrispondenza dell'UUID NIL:

/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i


1
Penso che [1-5] [0-9a-f] {3} non sia corretto. Ho un UUID valido che ha "b06a" in quella parte, e questo non ha funzionato per me.
Felipe Brahm,

1
@FelipeBrahm, [1-5] ha ragione secondo RFC, che 4 bit indicano la versione e ci sono solo 5 versioni.
rvignacio,

749d0000-0194-1005-2e05-08d61613bf2f fallisce per me nel violino
ruba il

1
Per curiosità, (perché) non sarebbe valido anche questo: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet,

58

regex in soccorso

/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test('01234567-9ABC-DEF0-1234-56789ABCDEF0');

o con parentesi

/^\{?[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}‌​\}?$/

3
o se potresti avere parentesi: / ^ \ {? [0-9a-fA-F] {8} - [0-9a-fA-F] {4} - [0-9a-fA-F] {4} - [0-9a-fA-F] {4} - [0-9a-fA-F] {12} \} $ / test ( '01234567-9ABC-DEF0-1234-56789ABCDEF0')?.;
Ryanb,

Questo non è del tutto corretto. manca che [1-5] (versione) avvia il 3 ° blocco e [89AB] (variante) avvia il 4 ° blocco. La risposta di Gambol fa bene.
Lupo,

7
Versione più concisa (ignorando le parentesi):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
c24w,

41

Se si desidera verificare o convalidare una versione UUID specifica, ecco le regex corrispondenti.

Nota che l'unica differenza è il numero di versione , che è spiegato nel 4.1.3. Versioncapitolo di UUID 4122 RFC .

Il numero di versione è il primo carattere del terzo gruppo [VERSION_NUMBER][0-9A-F]{3}::

  • UUID v1:

    /^[0-9A-F]{8}-[0-9A-F]{4}-[1][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
  • UUID v2:

    /^[0-9A-F]{8}-[0-9A-F]{4}-[2][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
  • UUID v3:

    /^[0-9A-F]{8}-[0-9A-F]{4}-[3][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
  • UUID v4:

    /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
  • UUID v5:

    /^[0-9A-F]{8}-[0-9A-F]{4}-[5][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i

39

Se si utilizza Node.js per lo sviluppo, si consiglia di utilizzare un pacchetto chiamato Validator. Include tutte le regex necessarie per convalidare versioni diverse di UUID e in più si ottengono varie altre funzioni per la convalida.

Ecco il link npm: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false

Interessante, ma sembra che si aspetti trattini? Ecco i quattro regex che sta attualmente usando - /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i e / o /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i e / o /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i e /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin

1
Il validatore supporta solo UUID v3-5 non v1
peteb

13

Oltre alla risposta di Gambol che farà il lavoro in quasi tutti i casi , tutte le risposte fornite finora mancano che la formattazione raggruppata (8-4-4-4-12) non è obbligatoria per codificare i GUID nel testo . È usato molto spesso ma ovviamente può essere valida anche una catena semplice di 32 cifre esadecimali. [1] regex enh :

/^[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$/i

[1] La questione è di circa controllo ing variabile s, quindi dovremmo includere il modulo di poco intuitivo pure.


Questo è il mio preferito. Ancora meglio{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
Mike Nelson

10

Tutti i regex specifici per tipo pubblicati finora non riescono sull'UUID zero "tipo 0", definito nella 4.1.7 della RFC come:

L'UUID nullo è una forma speciale di UUID specificata per avere tutti i 128 bit impostati su zero: 00000000-0000-0000-0000-000000000000

Per modificare la risposta di Wolf:

/^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-5][0-9a-f]{3}-?[089ab][0-9a-f]{3}-?[0-9a-f]{12}$/i

Oppure, per escludere correttamente un "tipo 0" senza tutti zeri, abbiamo il seguente (grazie a Luke):

/^(?:[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a‌​-f]{3}-?[0-9a-f]{12}‌​|00000000-0000-0000-‌​0000-000000000000)$/‌​i

Il primo segmento UUID dell'UUID nullo dovrebbe avere 8 zero, non 7. Il regex fornito non lo ha convalidato con 7.
Rich Seviora,

2
Il tuo aspetto è migliore ma consente alcuni UUID non validi, ad esempio: abcdef00-0000-0000-0000-000000000000 corrisponderebbe al tuo regex. Questa regex corrisponderà a UUID validi, incluso lo zero:/^(?:[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i
Luca

10

grazie a @usertatha con qualche modifica

function isUUID ( uuid ) {
    let s = "" + uuid;

    s = s.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$');
    if (s === null) {
      return false;
    }
    return true;
}

2

Penso che la risposta di Gambol sia quasi perfetta, ma fraintende RFC 4122 § 4.1.1. Sezione variante un po '.

Copre gli UUID Variant-1 (10xx = 8..b), ma non copre le varianti Variant-0 (0xxx = 0..7) e Variant-2 (110x = c..d) riservate alla compatibilità con le versioni precedenti, quindi sono UUID tecnicamente validi. Variant-4 (111x = e..f) è infatti riservato per un utilizzo futuro, quindi non sono attualmente validi.

Inoltre, il tipo 0 non è valido, tale "cifra" può essere 0 solo se è un UUID NIL (come menzionato nella risposta di Evan ).

Quindi penso che il regex più accurato conforme alle attuali specifiche RFC 4122 sia (compresi i trattini):

/^([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[0-9a-d][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i
                            ^                ^^^^^^
                    (0 type is not valid)  (only e..f variant digit is invalid currently)

1

Utilizzare il metodo .match () per verificare se String è UUID.

public boolean isUUID(String s){
    return s.match("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
}

Uncaught TypeError: s.matches non è una funzione
Deep Kakkar,

1
Lo script fornito non è Javascript, che è ciò che l'OP ha richiesto.
StefanJanssen,

Risposta corretta per rispondere ai commenti sopra. La soluzione ora funziona come previsto.
DeeZone

Non è ancora js.
ktilcu,

1

Una versione leggermente modificata delle risposte sopra scritte in modo più conciso. Ciò convaliderà qualsiasi GUID con trattini (comunque facilmente modificabile per rendere facoltativi i trattini). Ciò supporterà anche i caratteri maiuscoli e minuscoli che sono diventati la convenzione indipendentemente dalle specifiche:

/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i

La chiave qui è la parte ripetuta di seguito

(([0-9a-fA-F]{4}\-){3})

Che semplicemente ripete i 4 schemi di caratteri 3 volte


1
A-fdovrebbe essere A-Fcosì:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone il

se si inserisce il caso (/ i), perché ripetere af e poi AF?
Nimrod,

0

Un buon modo per farlo in Node è usare il ajvpacchetto ( https://github.com/epoberezkin/ajv ).

const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true, useDefault: true, verbose: true });
const uuidSchema = { type: 'string', format: 'uuid' };
ajv.validate(uuidSchema, 'bogus'); // returns false
ajv.validate(uuidSchema, 'd42a8273-a4fe-4eb2-b4ee-c1fc57eb9865'); // returns true with v4 GUID
ajv.validate(uuidSchema, '892717ce-3bd8-11ea-b77f-2e728ce88125'); // returns true with a v1 GUID

-1

Penso che un modo migliore sia usare il metodo statico di String per evitare quelle espressioni regolari.

    id = UUID.randomUUID();
    UUID uuid = UUID.fromString(id.toString());
    Assert.assertEquals(id.toString(), uuid.toString());

D'altro canto

   UUID uuidFalse = UUID.fromString("x");

genera java.lang.IllegalArgumentException: stringa UUID non valida: x

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.