¿Cómo determinar si una cadena es un UUID v4 válido? [duplicate]

7 minutos de lectura

avatar de usuario
rafael

Estoy haciendo un validador basado en UUID generado por el navegador del cliente, lo uso para identificar un cierto tipo de datos que envía el usuario; y me gustaría validar que el UUID que el cliente envía es de hecho un válido Versión 4 UUID.

Encontré este PHP preg_match UUID v4, está cerca pero no es exactamente lo que estoy buscando. Deseo saber si existe algo similar a is_empty() o strtodate() Donde si la cadena no es válida Envíos FALSE.

Podría hacerlo en base a la expresión regular, pero me gustaría algo más nativo para probarlo.

¿Algunas ideas?

23/11/2019 EDITAR: Acerca de la etiqueta duplicada, si bien el moderador es técnicamente correcto, esta pregunta se formuló con el objetivo de encontrar algo más para regex si existiera, y en segundo lugar, esta pregunta se ha convertido en una referencia para Pythoners y PHPers y tiene diferentes respuestas/enfoque para resuelven el problema y sus respuestas se explican mejor en general. Es por esto que considero que esta pregunta debe mantenerse

  • La pregunta es para PHP, pero para aquellos de ustedes que quieran hacer esto en Python, la segunda respuesta a continuación es muy buena.

    – jsbueno

    15 de enero de 2016 a las 2:00

avatar de usuario
Ωmega

Los UUID de la versión 4 tienen la forma xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx dónde x es cualquier dígito hexadecimal y y es uno de 8, 9, Ao B.

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

Para permitir letras minúsculas, use i modificador →

$UUIDv4 = '/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i';
preg_match($UUIDv4, $value) or die('Not valid UUID');

  • Antes de realizar la expresión regular, podría agregar un simple rápido IF() para probar si la longitud de la cadena es de 32 o 36 caracteres. Si no, no es una cadena hexadecimal UUID.

    – Basil Bourque

    15 de noviembre de 2013 a las 8:21


  • Formato adecuado de v4 UUID debe contener guionesya que se queda en la respuesta. es.wikipedia.org/wiki/…

    – Ωmega

    7 de julio de 2016 a las 1:03

  • Si no puede usar el modificador i, puede usar ^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3}-[89AB][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$

    – caballito

    18 de febrero de 2020 a las 15:25

  • Si no puede usar el i modificado, puede usar ^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$

    – Swaru

    4 de agosto de 2020 a las 8:49

avatar de usuario
Martín Tomas

Encontré esta pregunta mientras buscaba una respuesta de Python. Para ayudar a las personas en la misma situación, he añadido el Pitón solución.

Puedes usar el uuid módulo:

#!/usr/bin/env python

from uuid import UUID

def is_valid_uuid(uuid_to_test, version=4):
    """
    Check if uuid_to_test is a valid UUID.
    
     Parameters
    ----------
    uuid_to_test : str
    version : {1, 2, 3, 4}
    
     Returns
    -------
    `True` if uuid_to_test is a valid UUID, otherwise `False`.
    
     Examples
    --------
    >>> is_valid_uuid('c9bf9e57-1685-4c89-bafb-ff5af830be8a')
    True
    >>> is_valid_uuid('c9bf9e58')
    False
    """
    
    try:
        uuid_obj = UUID(uuid_to_test, version=version)
    except ValueError:
        return False
    return str(uuid_obj) == uuid_to_test


if __name__ == '__main__':
    import doctest
    doctest.testmod()

  • Debe quedar claro que lo que está mostrando no es PHP, que es de lo que se trata esta pregunta. Por lo tanto, no es exactamente trivial colocar este código y hacer que funcione, se necesitará algo de cuidado para usar el módulo Python UUID de PHP.

    – Garbee

    28/10/2015 a las 19:25

  • @Garbee ¡Gracias! No me di cuenta de eso, porque llegué a esta pregunta a través de Google. Obviamente, no leí la pregunta cuidadosamente. Sigo pensando que las personas que llegan a esta pregunta podrían estar interesadas en mi respuesta. Dejé en claro que mi respuesta es una solución de Python.

    – Martín Tomas

    28/10/2015 a las 20:52

  • @jsbueno De nada. Me gustan mucho esos comentarios ya que agregan información adicional y, tal como dijiste, pueden ignorarse en caso de que no los necesites 🙂

    – Martín Tomas

    15 de enero de 2016 a las 9:11

  • De ninguna manera le estoy pidiendo que los elimine. Mi intención era recordarle a cualquiera que use esto, que sin ellos, este es un 4 liner. Pero mientras estamos en eso, ¿es necesaria la comparación en la última línea?

    – jsbueno

    15 de enero de 2016 a las 12:17

  • @jsbueno En realidad, no estoy muy seguro de eso. Cuando escribí esto, pensé que era necesario. Si lo recuerdo correctamente, estaba relacionado con UUID “arreglando” algunos de los errores de entrada. Pero tendría que buscar el código UUID nuevamente.

    – Martín Tomas

    15 de enero de 2016 a las 16:42

avatar de usuario
slajma

Todas las respuestas existentes usan expresiones regulares. si estás usando Pitónes posible que desee considerar una try/except en caso de que no quieras usar expresiones regulares:
(Un poco más corto que la respuesta anterior).

Nuestro validador sería entonces:

import uuid

def is_valid_uuid(val):
    try:
        uuid.UUID(str(val))
        return True
    except ValueError:
        return False

>>> is_valid_uuid(1)
False
>>> is_valid_uuid("123-UUID-wannabe")
False
>>> is_valid_uuid({"A":"b"})
False
>>> is_valid_uuid([1, 2, 3])
False
>>> is_valid_uuid(uuid.uuid4())
True
>>> is_valid_uuid(str(uuid.uuid4()))
True
>>> is_valid_uuid(uuid.uuid4().hex)
True
>>> is_valid_uuid(uuid.uuid3(uuid.NAMESPACE_DNS, 'example.net'))
True
>>> is_valid_uuid(uuid.uuid5(uuid.NAMESPACE_DNS, 'example.net'))
True
>>> is_valid_uuid("{20f5484b-88ae-49b0-8af0-3a389b4917dd}")
True
>>> is_valid_uuid("20f5484b88ae49b08af03a389b4917dd")
True

  • Tenga cuidado con las variantes de sintaxis de UUID que acepta uuid.UUID(): “{20f5484b-88ae-49b0-8af0-3a389b4917dd}”, “20f5484b88ae49b08af03a389b4917dd”

    – Peters Caune

    20 de febrero de 2020 a las 8:30

  • Gracias @PēterisCaune buena adición – el caso con .hex esencialmente cubre el último que agregó, pero vale la pena agregarlo independientemente. No estaba al tanto del caso “{uuid}”.

    – slajma

    31 de marzo de 2020 a las 5:07

  • También esto es cierto. is_valid_uuid('-2b1eb780-8a03-4031-b1e5-2f7674c60df3') >> Verdadero

    – Vikram Ray

    25 de agosto de 2021 a las 5:30

import re

UUID_PATTERN = re.compile(r'^[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}$', re.IGNORECASE)
uuid = '20f5484b-88ae-49b0-8af0-3a389b4917dd'

if UUID_PATTERN.match(uuid):
    return True
else:
    return False

avatar de usuario
Las nueces

Si solo lo necesita por seguridad (por ejemplo, si necesita imprimirlo en un código javascript y desea evitar XSS), realmente no importa la posición de los guiones, por lo que es solo:

 /^[a-f0-9\-]{36}$/i

https://regex101.com/r/MDqB2Z/11


(No es específico para v4, pero generalmente una aplicación bien escrita los almacena como BINARIO (16) después de haber eliminado los guiones, por lo que si algo está mal, simplemente no encontrará el objeto y arrojará 404, es posible que no se necesite sobrevalidación).

  • esto no responde la pregunta.

    – Rafael

    16 de abril de 2018 a las 15:41

  • Sí responde quién busca la validación de uuid más simple.

    – Las nueces

    10 de agosto de 2020 a las 13:42

  • Esto no validará un UUID v4 específicamente, ya que requiere un 4 y [8-b] en las posiciones adecuadas. Sin embargo, es bueno garantizar el conjunto de caracteres adecuado.

    – capitánGeech

    4 oct 2020 a las 19:34


  • esto no responde la pregunta.

    – Rafael

    16 de abril de 2018 a las 15:41

  • Sí responde quién busca la validación de uuid más simple.

    – Las nueces

    10 de agosto de 2020 a las 13:42

  • Esto no validará un UUID v4 específicamente, ya que requiere un 4 y [8-b] en las posiciones adecuadas. Sin embargo, es bueno garantizar el conjunto de caracteres adecuado.

    – capitánGeech

    4 oct 2020 a las 19:34


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad