Como testar UUID / GUID válido?

270

Como verificar se a variável contém um identificador UUID / GUID válido?

No momento, estou interessado apenas na validação dos tipos 1 e 4, mas não deve ser uma limitação para suas respostas.

Marek Sebera
fonte
no formato de cadeia, não hex, não bin, ou eu não sei o que você pedir
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 você não pode excluir variáveis contendo uma cadeia de 32 dígitos hexadecimais consecutivos (sem agrupamento), ter um olhar para a minha resposta
Lobo

Respostas:

413

Atualmente, os UUIDs são os especificados na RFC4122. Um caso de borda muitas vezes negligenciado é o NIL UUID, observado aqui . A seguinte expressão regular leva isso em consideração e retornará uma correspondência para um NUUUID. Veja abaixo um UUID que aceita apenas UUIDs não NIL. Ambas as soluções são para as versões 1 a 5 (consulte o primeiro caractere do terceiro bloco).

Portanto, para validar um 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

... garante que você tenha um UUID formatado canonicamente que seja da versão 1 a 5 e seja a variante apropriada conforme RFC4122.

NOTA: Suspensórios {e }não são canônicos. Eles são um artefato de alguns sistemas e usos.

Fácil modificar a regex acima para atender aos requisitos da pergunta original.

DICA: grupo / captura de expressões regulares

Para evitar a correspondência de NIL UUID:

/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
Gambol
fonte
9
+1 Por mencionar a Internet Engineering Task Force (IETF)
mate64
1
Eu acho que [1-5] [0-9a-f] {3} está incorreto. Eu tenho um UUID válido com "b06a" nessa parte e isso estava falhando para mim.
Felipe Brahm
1
@FelipeBrahm, [1-5] está certo de acordo com a RFC, que 4 bits indicam a versão e existem apenas 5 versões.
rvignacio
749d0000-0194-1005-2e05-08d61613bf2f falha para mim no violino
robs
1
Por curiosidade, (porque) não seria muito válido o seguinte: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet
58

regex para o resgate

/^[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');

ou com colchetes

/^\{?[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
fonte
3
ou se você tiver colchetes: / ^ \ {? [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
Isso não está correto. falta que [1-5] (versão) inicie o 3º bloco e [89AB] (variante) inicie o 4º bloco. A resposta de Gambol faz certo.
Lobo
7
Versão mais concisa (ignorando colchetes):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
c24w 16/10
41

Se você deseja verificar ou validar uma versão UUID específica, aqui estão as regexes correspondentes.

Observe que a única diferença é o número da versão , explicado no 4.1.3. Versioncapítulo do RFC UUID 4122 .

O número da versão é o primeiro caractere do terceiro 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
fonte
39

Se você estiver usando o Node.js. para desenvolvimento, é recomendável usar um pacote chamado Validator. Ele inclui todas as expressões regulares necessárias para validar versões diferentes de UUIDs, além de você obter várias outras funções para validação.

Aqui está o link npm: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false
Neeraj Sharma
fonte
Interessante, mas parece que espera hífens? Aqui estão os quatro expressões regulares está usando atualmente - /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i e / ou /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i e / ou /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i e / ou /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin
1
Validador suporta apenas UUID v3-5 não v1
peteb
13

Ao lado da resposta de Gambol, que fará o trabalho em quase todos os casos , todas as respostas dadas até agora perderam a formatação agrupada (8-4-4-4-12) não é obrigatória para codificar GUIDs em texto . É usado com muita frequência, mas obviamente também uma cadeia simples de 32 dígitos hexadecimais pode ser válida. [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] A questão é verificar as variáveis s, portanto devemos incluir também o formulário não amigável ao usuário.

Lobo
fonte
Este é o meu favorito. Melhor ainda{?[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 as regexes específicas de tipo postadas até agora estão falhando no UUID "tipo 0" nulo, definido em 4.1.7 da RFC como:

O UUID nulo é uma forma especial de UUID especificada para ter todos os 128 bits definidos como zero: 00000000-0000-0000-0000-000000000000

Para modificar a resposta 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

Ou, para excluir corretamente um "tipo 0" sem todos os zeros, temos o seguinte (graças 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
fonte
Primeiro segmento de UUID do UUID nulo deve ter 8 zeros, não 7. A regex fornecido não validar com 7.
rico Seviora
2
A sua aparência é mais agradável, mas permite alguns UUIDs inválidos, por exemplo: abcdef00-0000-0000-0000-000000000000 corresponderiam ao seu regex. Esse regex corresponderá a UUIDs válidos, incluindo o 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
Luke
10

graças a @usertatha com algumas modificações

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
fonte
2

Acho que a resposta de Gambol é quase perfeita, mas interpreta mal a RFC 4122 § 4.1.1. Seção de variantes um pouco.

Abrange UUIDs da variante-1 (10xx = 8..b), mas não abrange as variantes da variante-0 (0xxx = 0..7) e da variante-2 (110x = c..d) que são reservadas para compatibilidade com versões anteriores, então eles são UUIDs tecnicamente válidos. A variante-4 (111x = e..f) é realmente reservada para uso futuro, portanto, elas não são válidas no momento.

Além disso, o tipo 0 não é válido, esse "dígito" só pode ser 0 se for um NIL UUID (como mencionado na resposta de Evan ).

Então eu acho que o regex mais preciso que está em conformidade com a especificação atual RFC 4122 é (incluindo hífens):

/^([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
fonte
1

Use o método .match () para verificar 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}$");
}
userTatha
fonte
TypeError não capturado: s.matches não é uma função
Profundo Kakkar
1
O script fornecido não é Javascript, o que o OP solicitou.
StefanJanssen
Resposta ajustada para abordar os comentários acima. A solução agora funciona como esperado.
DeeZone 14/01
Isso ainda não é js.
ktilcu
1

Uma versão ligeiramente modificada das respostas acima, escrita de maneira mais concisa. Isso validará qualquer GUID com hífens (por mais que seja facilmente modificado para tornar os hífens opcionais). Isso também suporta caracteres maiúsculos e minúsculos que se tornaram a convenção, independentemente da especificação:

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

A chave aqui é a parte repetida abaixo

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

Que simplesmente repete os 4 padrões de caracteres 3 vezes

James Morrison
fonte
1
A-fdeve ser A-Fassim:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone 19/01
se você tiver um caso (/ i), por que repetir af e depois AF?
Nimrod
0

Uma boa maneira de fazer isso no Node é usar o ajvpacote ( 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
fonte
-1

Eu acho que uma maneira melhor é usar o método estático fromString para evitar essas expressões regulares.

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

Por outro lado

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

lança java.lang.IllegalArgumentException: string UUID inválida: x

Werner Diwischek
fonte