¿Cómo probar un UUID / GUID válido?

270

¿Cómo verificar si la variable contiene un identificador UUID / GUID válido?

Actualmente solo estoy interesado en validar los tipos 1 y 4, pero no debería ser una limitación para sus respuestas.

Marek Sebera
fuente
en formato de cadena, no hexadecimal, no bin, o no sé qué pides
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
Si no puede excluir variables que contienen una cadena de 32 dígitos hexadecimales consecutivos (sin agrupar), eche un vistazo a mi respuesta
Wolf

Respuestas:

413

Actualmente, los UUID son los especificados en RFC4122. Un caso marginal a menudo descuidado es el UUID NIL, que se indica aquí . La siguiente expresión regular toma esto en cuenta y devolverá una coincidencia para un UUID NIL. Consulte a continuación un UUID que solo acepta UUID no NIL. Ambas soluciones son para las versiones 1 a 5 (ver el primer carácter del tercer bloque).

Por lo tanto, para validar 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

... asegura que tiene un UUID con formato canónico que es de la Versión 1 a la 5 y es la Variante apropiada según RFC4122.

NOTA: Las llaves {y }no son canónicas. Son un artefacto de algunos sistemas y usos.

Fácil de modificar la expresión regular anterior para cumplir con los requisitos de la pregunta original.

SUGERENCIA: grupo / capturas de expresiones regulares

Para evitar la coincidencia de 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
Retozar
fuente
1
Creo que [1-5] [0-9a-f] {3} es incorrecto. Tengo un UUID válido que tiene "b06a" en esa parte, y esto me estaba fallando.
Felipe Brahm
1
@FelipeBrahm, [1-5] tiene razón según RFC, que 4 bits indican la versión, y solo hay 5 versiones.
rvignacio
749d0000-0194-1005-2e05-08d61613bf2f falla para mí en el violín
roba el
1
Por curiosidad, (por qué) no sería válido lo siguiente: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet
58

regex al rescate

/^[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 paréntesis

/^\{?[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}‌​\}?$/
ryanb
fuente
3
o si puede tener corchetes: / ^ \ {? [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} \}? $ /. Prueba ('01234567-9ABC-DEF0-1234-56789ABCDEF0');
ryanb
Esto no es del todo correcto. se pierde que [1-5] (versión) inicia el 3er bloque y [89AB] (variante) inicia el 4to bloque. La respuesta de Gambol lo hace bien.
Lobo
77
Versión más concisa (ignorando paréntesis):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
c24w
41

Si desea verificar o validar una versión específica de UUID, aquí están las expresiones regulares correspondientes.

Tenga en cuenta que la única diferencia es el número de versión , que se explica en el 4.1.3. Versioncapítulo de UUID 4122 RFC .

El número de versión es el primer carácter del tercer grupo [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
Ivan Gabriele
fuente
39

Si está utilizando Node.js para el desarrollo, se recomienda utilizar un paquete llamado Validator. Incluye todas las expresiones regulares requeridas para validar diferentes versiones de UUID, además de obtener varias otras funciones para la validación.

Aquí está el enlace npm: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false
Neeraj Sharma
fuente
Interesante, pero parece que espera guiones? Aquí están las cuatro expresiones regulares que está usando actualmente - /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i y / o /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i y / o /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i y / o /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin
1
Validator solo es compatible con UUID v3-5 no v1
peteb
13

Además de la respuesta de Gambol que hará el trabajo en casi todos los casos , todas las respuestas dadas hasta ahora se perdieron y el formato agrupado (8-4-4-4-12) no es obligatorio para codificar GUID en el texto . Se usa con mucha frecuencia, pero obviamente también puede ser válida una cadena simple de 32 dígitos hexadecimales. [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 pregunta es sobre la verificación de la variable s, por lo que también debemos incluir la forma amigable para el usuario.

Lobo
fuente
Este es mi favorito. Mejor aún{?[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

Todas las expresiones regulares específicas de tipo publicadas hasta ahora están fallando en el UUID nulo "tipo 0", definido en 4.1.7 del RFC como:

El UUID nulo es una forma especial de UUID que se especifica para tener todos los 128 bits establecidos en cero: 00000000-0000-0000-0000-000000000000

Para modificar la respuesta de 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

O, para excluir correctamente un "tipo 0" sin todos los ceros, tenemos lo siguiente (gracias 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
Evan Edwards
fuente
El primer segmento UUID del UUID nulo debería tener 8 ceros, no 7. La expresión regular proporcionada no lo validó con 7.
Rich Seviora
2
El suyo se ve mejor, pero permite algunos UUID no válidos, por ejemplo: abcdef00-0000-0000-0000-000000000000 coincidiría con su expresión regular. Esta expresión regular coincidirá con UUID válidos, incluido el nulo:/^(?:[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
Lucas
10

gracias a @usertatha con alguna modificación

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;
}
Souhaieb
fuente
2

Creo que la respuesta de Gambol es casi perfecta, pero malinterpreta el RFC 4122 § 4.1.1. Sección variante un poco.

Cubre los UUID de variante-1 (10xx = 8..b), pero no cubre las variantes de variante-0 (0xxx = 0..7) y variante-2 (110x = c..d) que están reservadas para compatibilidad con versiones anteriores, entonces son UUID técnicamente válidos. La variante 4 (111x = e..f) está reservada para uso futuro, por lo que no son válidas actualmente.

Además, el tipo 0 no es válido, ese "dígito" solo puede ser 0 si es un UUID NIL (como se menciona en la respuesta de Evan ).

Así que creo que la expresión regular más precisa que cumple con la especificación RFC 4122 actual es (incluidos los guiones):

/^([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)
B. Zoli
fuente
1

Use el método .match () para verificar si String es 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}$");
}
userTatha
fuente
TypeError no capturado: s.matches no es una función
Deep Kakkar
1
El script dado no es Javascript, que es lo que solicitó el OP.
StefanJanssen
Respuesta ajustada para abordar los comentarios anteriores. La solución ahora funciona como se espera.
DeeZone
Eso todavía no es js.
ktilcu
1

Una versión ligeramente modificada de las respuestas anteriores escrita de una manera más concisa. Esto validará cualquier GUID con guiones (sin embargo, se modifica fácilmente para que los guiones sean opcionales). Esto también admitirá caracteres en mayúsculas y minúsculas, lo que se ha convertido en la convención independientemente de la especificación:

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

La clave aquí es la parte que se repite a continuación.

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

Que simplemente repite los 4 patrones de char 3 veces

James Morrison
fuente
1
A-fdebería ser A-Fasí:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone
Si no está en caso (/ i), ¿por qué repetir AF y luego AF?
Nimrod
0

Una buena manera de hacerlo en Node es usar el ajvpaquete ( 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
blackcatweb
fuente
-1

Creo que una mejor manera es usar el método estático fromString para evitar esas expresiones regulares.

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

Por otra parte

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

lanza java.lang.IllegalArgumentException: cadena de UUID no válida: x

Werner Diwischek
fuente