web-dev-qa-db-fra.com

Comment déterminer si une chaîne est un UUID v4 valide?

Je crée un validateur basé sur UUID généré par le navigateur client, je l'utilise pour identifier un certain type de données que l'utilisateur envoie; et voudrait valider que la UUID que le client envoie est en fait un Version 4UUID valide.

J'ai trouvé ceci PHP preg_match UUID v4 , c'est proche mais ce n'est pas exactement ce que je recherche. Je souhaite savoir s'il existe quelque chose de similaire à is_empty() ou strtodate() Où si la chaîne n'est pas valide Envoie FALSE.

Je pourrais le faire en fonction de l’expression régulière, mais j’aimerais quelque chose de plus natif pour le tester.

Des idées?

41
Rafael

Les UUID de la version 4 ont la forme xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxx est un chiffre hexadécimal et y est l'un des 8, 9, A ou B.

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

Pour autoriser les lettres minuscules, utilisez le modificateur i

$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');
71
Ωmega

J'ai trouvé cette question alors que je cherchais une réponse en Python. Pour aider les personnes dans la même situation, j'ai ajouté la solution Python.

Vous pouvez utiliser le module uuid :

#!/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:
        return False

    return str(uuid_obj) == uuid_to_test


if __== '__main__':
    import doctest
    doctest.testmod()
27
Martin Thoma
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
4
Andrey Shipilov

Si vous n'en avez besoin que pour des raisons de sécurité (par exemple, si vous avez besoin de l'imprimer avec un code javascript et que vous voulez éviter XSS), la position des tirets n'a pas d'importance, c'est donc:

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

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

2
the_nuts

Les réponses existantes utilisent toutes regexSi vous utilisez python, vous pouvez envisager un try/except si vous ne souhaitez pas utiliser regex: (bit plus court que la réponse ci-dessus).

Notre validateur serait alors:

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
1
slajma