103

我正在根据客户端浏览器生成的UUID制作验证器,我用它来识别用户发送的某种类型的数据;并想验证该UUID客户端发送它实际上是有效的Version 4 UUID

我找到了这个PHP preg_match UUID v4,它很接近但不完全是我想要的。我想知道是否存在类似于is_empty()strtodate()Where if string is not valid Sends 的东西FALSE

我可以基于正则表达式来做,但我想要更原生的东西来测试它。

有任何想法吗?

2019 年 11 月 23 日编辑:关于重复标签,虽然版主在技术上是正确的,但这个问题的制定目标是 fibd 其他东西,如果存在正则表达式,第二,这个问题已成为 Pythoners 和 PHPers 的参考和有不同的答案/方法来解决问题,并且他们的答案通常得到更好的解释。这就是为什么我认为应该坚持这个问题

4

5 回答 5

147

版本 4 UUID 的形式xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxx任何十六进制数字,并且y89A或之一B

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

要允许小写字母,请使用i修饰符 →</p>

$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');
于 2013-11-14T22:38:03.343 回答
130

我在寻找 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()
于 2015-10-20T19:43:04.230 回答
31

所有现有的答案都使用正则表达式。如果您使用的是Python,则可能需要考虑 atry/except以防您不想使用正则表达式:( 比上面的答案短一点)。

我们的验证器将是:

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
于 2019-01-18T12:32:31.270 回答
6
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
于 2016-06-30T02:58:46.310 回答
4

如果您只需要它以确保安全(例如,如果您需要在 javascript 代码中打印它并且您想避免 XSS),那么破折号的位置并不重要,所以它只是:

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

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


(它并不特定于 v4,但通常一个编写良好的应用程序在删除破折号后将它们存储为 BINARY(16),因此如果出现问题,它将根本找不到对象并抛出 404,可能不需要过度验证)。

于 2017-06-28T15:13:07.210 回答