IP地址验证

Mar*_*erl 14 .net c# ip validation parsing

我正在重构我的代码,并希望使用该IPAddress.TryParse方法来验证字符串是否是有效的IPv4地址而不是使用正则表达式:

public static bool IsIPv4(string value)
{
    IPAddress address;

    if (IPAddress.TryParse(value, out address))
    {
        if (address.AddressFamily == AddressFamily.InterNetwork)
        {
            return true;
        }
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

我的单元测试现在失败了,因为这些输入值返回true并被解析为以下IPAddress对象:

value = "0.0.0.0"      ->  address = {0.0.0.0}
value = "255.255.255"  ->  address = {255.255.0.255}
value = "65536"        ->  address = {0.1.0.0}
Run Code Online (Sandbox Code Playgroud)

这有意义吗?我可以看到这0.0.0.0在技​​术上是一个有效的IPv4地址,即使用户输入它也没有意义.那两个呢?为什么他们以他们的方式进行转换,我应该将它们视为有效,即使它对用户来说可能不是透明的,用户可能只是忘记输入句点(65536而不是6.5.5.36).

任何帮助都非常感谢.

小智 21

IPAddress.TryParse()的工作不是检查字符串是否是有效的IP地址,而是检查字符串的内容是否可以解析(即;转换)为有效的IP地址.

实际上,您的测试用例中的所有选项都可以解析为表示和IP.它归结为您的测试用例是有效的.问题是您的测试用例的数据无效,或者您没有在测试用例中使用正确的工具来获得预期的结果.

如果你专门测试一个有效的IPv4,只有4个四边形(每个是一个0到255之间的整数),并且想要避免使用正则表达式,你可以改为拆分然后解析并验证.

    public static bool IsIPv4(string value)
    {
        var quads = value.Split('.');

        // if we do not have 4 quads, return false
        if (!(quads.Length==4)) return false;

        // for each quad
        foreach(var quad in quads) 
        {
            int q;
            // if parse fails 
            // or length of parsed int != length of quad string (i.e.; '1' vs '001')
            // or parsed int < 0
            // or parsed int > 255
            // return false
            if (!Int32.TryParse(quad, out q) 
                || !q.ToString().Length.Equals(quad.Length) 
                || q < 0 
                || q > 255) { return false; }

        }

        return true;
    }
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案,但这会更容易阅读:if(quads.Length!= 4)返回false; (2认同)

mqp*_*mqp 9

IPAddress.Parse通过指出输入较少的部分可以方便地输入A类和B类地址,看起来像是合理化这种行为的文档.如果你想强制一个四部分的地址,你可能只想检查地址中有三个句点,然后再将其输入IPAddress.TryParse,我想.

一些代码供您参考:

// verify that IP consists of 4 parts
if (value.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Length == 4)
{
    IPAddress ipAddr;
    if (IPAddress.TryParse(value, out ipAddr))
    {
        // IP is valid
    }
    else
        // invalid IP
}
else
    // invalid IP
Run Code Online (Sandbox Code Playgroud)


Jef*_*dge 6

如果您想对输入非常严格,那么您可以比较ToString()解析的版本,IPAddress如果它们不同则拒绝输入.

全零地址和其他类似的东西必须作为特殊情况处理.


小智 5

我建议:

    public bool IsValidIp(string addr)
    {
        IPAddress ip;
        bool valid = !string.IsNullOrEmpty(addr) && IPAddress.TryParse(addr, out ip);
        return valid;
    }
Run Code Online (Sandbox Code Playgroud)

  • 这不回答这个问题.它只对问题的范围添加空检查. (3认同)
  • 不,它根本不是...... (2认同)