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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19989481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 20:19:43  来源:igfitidea点击:

How to determine if a string is a valid v4 UUID?

phpregexuuid

提问by Rafael

I'm making a validator based on UUIDgenerated by client browser, I use this to identify a certain type data that the user sends; and would like to validate that the UUIDthat client sends it is in fact a valid Version 4UUID.

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

I found this 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.

我找到了这个PHP preg_match UUID v4,它很接近但不完全是我正在寻找的。我想知道是否存在类似于is_empty()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

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

回答by ?mega

Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxwhere xis any hexadecimal digit and yis one of 8, 9, A, or B.

版本4的UUID具有形式xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx其中x是任意十六进制数字和y是下列之一89A,或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 imodifier →

要允许小写字母,请使用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');

回答by Martin Thoma

I found this question while I was looking for a Python answer. To help people in the same situation, I've added the Pythonsolution.

我在寻找 Python 答案时发现了这个问题。为了帮助处于相同情况的人,我添加了Python解决方案。

You can use the uuidmodule:

您可以使用该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()

回答by slajma

All the existing answers use regex. If you're using Python, you might want to consider a try/exceptin case you don't want to use regex: (Bit shorter than the answer above).

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

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

回答by Andrey Shipilov

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

回答by the_nuts

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:

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

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

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

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