How to determine if a string is a valid v4 UUID?
PhpRegexUuidPhp Problem Overview
I'm making a validator based on UUID generated by client browser, I use this to identify a certain type data that the user sends; and would like to validate that the UUID
that client sends it is in fact a valid Version 4 UUID
.
I found this https://stackoverflow.com/questions/6223185/php-preg-match-uuid-v4, it's close but not exactly what I'm looking for. I wish to know if exists something similar to is_empty()
or strtodate()
Where if string is not valid Sends FALSE
.
I could do based on the regular expression but I would like something more native to test it.
Any ideas?
11/23/2019 EDIT: About the duplicate tag, while the moderator is technicallly correct, this question was formulated with the goal of fibd something else to regex if existed, and in second place this question has become a reference to Pythoners and PHPers and has a different answers/approach to solve the problem and their answers are better explained in general. This is why I consider this question should be perserved
Php Solutions
Solution 1 - Php
Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
where x
is any hexadecimal digit and y
is one of 8
, 9
, A
, or B
.
^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$
To allow lowercase letters, use i
modifier →
$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');
Solution 2 - Php
I found this question while I was looking for a Python answer. To help people in the same situation, I've added the Python solution.
You can use the uuid
module:
#!/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()
Solution 3 - Php
All the existing answers use regex. If you're using Python, you might want to consider a try/except
in case you don't want to use regex:
(Bit shorter than the answer above).
Our validator would then be:
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
Solution 4 - Php
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
Solution 5 - Php
If you only need it for security (for example if you need to print it in a javascript code and you want to avoid XSS) it doesn't really matter the position of the dashes, so it's just:
/^[a-f0-9\-]{36}$/i
https://regex101.com/r/MDqB2Z/11
(It's not specific for v4, but usually a well written application store them as BINARY(16) after having dropped the dashes, so if something is wrong it will simply not find the object and throw 404, overvalidation may not be needed).