如何确定字符串是否是有效的v4 UUID?

Raf*_*ael 52 php regex uuid

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

我发现这个PHP preg_match UUID v4,它很接近,但不完全是我正在寻找的.我想知道是否存在类似于is_empty()strtodate()如果字符串无效的地方发送FALSE.

我可以根据正则表达式做,但我想要更原生的东西来测试它.

有任何想法吗?

Ωme*_*ega 86

版本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}$
Run Code Online (Sandbox Code Playgroud)

要允许使用小写字母,请使用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');
Run Code Online (Sandbox Code Playgroud)

  • 在执行正则表达式之前,我可能会添加一个简单的快速`IF()`来测试字符串的长度是32还是36个字符.如果没有,它不是UUID十六进制字符串. (3认同)

Mar*_*oma 36

我在寻找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()
Run Code Online (Sandbox Code Playgroud)

  • @Garbee谢谢!我没注意到,因为我是通过谷歌来回答这个问题的.显然,我没有仔细阅读这个问题.我仍然认为提出这个问题的人可能会对我的回答感兴趣.我明确表示我的答案是Python解决方案. (6认同)
  • 应该清楚的是,你所展示的不是PHP,这就是这个问题所要求的.因此,删除此代码并使其工作并不是一件容易的事情,因此需要谨慎使用PHP中的Python UUID模块. (3认同)
  • 我绝不要求您将其删除-我的目的是提醒使用此工具的任何人,没有这些,这是4排纸。但是,尽管我们正在这样做-是否需要在最后一行进行比较? (2认同)
  • @jsbueno 我实际上不太确定。当我写这篇文章时,我认为这是必要的。如果我记得正确,它与 UUID“修复”一些输入错误有关。但我必须再次查看 UUID 代码。 (2认同)
  • 这个答案是错误的。Python 不会总是引发 ValueError。有时它会默默地修复输入。uuid.UUID('6a3f6f5c-8df8-5b4e-8ec3-a8b2df62a40b', version=4) UUID('6a3f6f5c-8df8-4b4e-8ec3-a8b2df62a40b') 请注意(中间的 5b4e 块!) (2认同)

And*_*lov 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
Run Code Online (Sandbox Code Playgroud)

  • 也许你可以解释一下?顺便说一句:`return UUID_PATTERN.match(uuid)`? (3认同)
  • @AndreyShipilov 可能他不明白为什么当问题要求 php 时你用 python 代码回答 (3认同)

sla*_*jma 5

现有的所有答案都使用正则表达式。如果您使用的是Python,则不妨try/except使用regex :( 比上面的答案短一点)。

我们的验证器将是:

import uuid

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

Run Code Online (Sandbox Code Playgroud)
>>> 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
Run Code Online (Sandbox Code Playgroud)