Как определить, является ли строка допустимым UUID v4?
Я делаю валидатор на основе UUID, сгенерированного браузером клиента, я использую его для идентификации данных определенного типа, которые отправляет пользователь; и хотел бы подтвердить, что UUID
, который отправляет клиент, на самом деле является действительной версией 4 UUID
.
Я нашел этот PHP preg_match UUID v4, он близко, но не совсем то, что я ищу. Я хотел бы знать, существует ли что-то похожее на is_empty()
или strtodate()
Где, если строка недопустима Отправляет FALSE
.
Я мог бы сделать это на основе регулярного выражения, но я хотел бы, чтобы что-то более родное для его проверки.
Есть идеи?
Ответы
Ответ 1
Версия 4 UUID имеют форму xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
, где x
- любая шестнадцатеричная цифра, а y
- одна из 8
, 9
, A
или B
.
^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$
Чтобы разрешить строчные буквы, используйте модификатор 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');
Ответ 2
Я нашел этот вопрос, пока искал ответ на языке Python. Чтобы помочь людям в такой же ситуации, я добавил решение Python.
Вы можете использовать модуль 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 ValueError:
return False
return str(uuid_obj) == uuid_to_test
if __name__ == '__main__':
import doctest
doctest.testmod()
Ответ 3
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
Все существующие ответы используют regex. Если вы используете python, вы можете рассмотреть try/except
если вы не хотите использовать regex: (немного короче, чем ответ выше).
Наш валидатор будет:
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
Ответ 5
Если вам нужна только безопасность (например, если вам нужно распечатать его в коде javascript, и вы хотите избежать XSS), это не имеет особого значения для позиции тире, поэтому просто:
/^[a-z0-9\-]{36}$/i
https://regex101.com/r/MDqB2Z/1