如何在.net中验证Guid

13
请告诉我如何在.NET中验证GUID并确保它始终是唯一的?

1
如果所有生成器都遵守规则,Guid始终是唯一的:http://blogs.msdn.com/b/oldnewthing/archive/2008/06/27/8659071.aspx - Daniel Little
8个回答

31

Guid通常有99.99999999999999999999999999999999%的唯一性。

这取决于您所说的“验证”是什么意思?

用于确定Guid字符串是否确实为Guid的代码如下所示

private static Regex isGuid = 
      new Regex(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", RegexOptions.Compiled);

internal static bool IsGuid(string candidate, out Guid output)
{
    bool isValid = false;
    output = Guid.Empty;

    if(candidate != null)
    {
   
        if (isGuid.IsMatch(candidate))
        {
            output=new Guid(candidate);
            isValid = true;
        }
    }

    return isValid;
}

+1 尝试不使用异常,-1 因为 Guid 可以有其他格式,当前方法将对以下情况抛出异常:"{230a0f8b-81fb-4052-866e-9ac6a7611c77"。 - João Angelo
6
在.NET 4.0中,我们终于看到了Guid.TryParse()的引入,这显然比使用正则表达式更可取。不过目前来说,这已经足够且可接受了。 - Wim
Guid不是随机的,也许有一种方法可以检查它们是否符合这些标准:http://blogs.msdn.com/b/oldnewthing/archive/2008/06/27/8659071.aspx - Daniel Little

13

2^128是一个非常大的数字。它比宇宙寿命内皮秒数量多十亿倍。这个数字太大了,无法验证,答案注定是“42”。使用这些数字的目的在于您不必进行验证。如果您担心出现重复,则您的担忧是错误的原因。机器被流星撞击摧毁的几率要大得多。

小心!


2
这里提供了一个非正则表达式的答案,速度应该很快:
public static bool IsHex(this char c)
{
    return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}

public static bool IsGuid(this string s)
{
    // Length of a proper GUID, without any surrounding braces.
    const int len_without_braces = 36;

    // Delimiter for GUID data parts.
    const char delim = '-';

    // Delimiter positions.
    const int d_0 = 8;
    const int d_1 = 13;
    const int d_2 = 18;
    const int d_3 = 23;

    // Before Delimiter positions.
    const int bd_0 = 7;
    const int bd_1 = 12;
    const int bd_2 = 17;
    const int bd_3 = 22;

    if (s == null)
        return false;

    if (s.Length != len_without_braces)
        return false;

    if (s[d_0] != delim ||
        s[d_1] != delim ||
        s[d_2] != delim ||
        s[d_3] != delim)
        return false;

    for (int i = 0;
        i < s.Length;
        i = i + (i == bd_0 ||
                i == bd_1 ||
                i == bd_2 ||
                i == bd_3
                ? 2 : 1))
    {
        if (!IsHex(s[i])) return false;
    }

    return true;
}

1

你无法验证GUID的唯一性。你只能希望它是由一个生成唯一16字节的工具生成的。至于验证,这段简单的代码可能会起作用(假设你正在处理GUID的字符串表示):

bool ValidateGuid(string theGuid)
{
  try { Guid aG = new Guid(theGuid); }
  catch { return false; }

  return true;
}

1
那是走捷径的方式。请记住,异常应仅用于非常时期,而不是用来验证类型。 - Kyle Rosendo
3
是的,但使用正则表达式会限制 GUID 字符串表示的格式。例如,在您的代码中,格式只包含破折号。 - Kerido
是的,写大量代码来完成同样的任务绝不是“捷径”。如果这是一个单元测试呢?那么它就可以被接受吗? - iGanja

0
在 .net 4 中,您可以使用这个扩展方法。
public static class GuidExtensions
    {
        public static bool IsGuid(this string value)
        {
            Guid output;
            return Guid.TryParse(value, out output);
        }
    }

0

我为此编写了一个扩展程序

public static bool TryParseGuid(this Guid? guidString)
       {
           if (guidString != null && guidString != Guid.Empty)
           {
               if (Guid.TryParse(guidString.ToString(), out _))
               {
                   return true;
               }
               else
                   return false;
           }

           return false;
       }

方法名TryParseGuid通常会暗示解析输出作为out参数返回(例如Enum.TryParse等)。考虑将此扩展方法重命名为IsGuidValid或类似名称,这将清楚地指示它返回bool - rsobon

0

如果你正在寻找一种确定是否为实际的 .Net Guid 类型格式的方法,请看这篇文章。一个快速的正则表达式就可以解决问题。


0

这个问题已经在这篇帖子中讨论过了。你可以找到更多有趣的细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接