IP地址验证

时间:2011-02-23 20:37:15

标签: c# .net parsing validation ip

我正在重构我的代码并希望使用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;
}

我的单元测试现在失败了,因为这些输入值返回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}

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

非常感谢任何帮助。

10 个答案:

答案 0 :(得分: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;
    }

答案 1 :(得分: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

答案 2 :(得分:6)

如果您想对输入非常严格,那么您可以比较解析后的ToString()的{​​{1}}版本,如果输入不同,则拒绝输入。

全零地址和其他此类事情必须作为特殊情况处理。

答案 3 :(得分:5)

我建议:

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

答案 4 :(得分:4)

    public static bool IsIPv4(string ipAddress)
    {
        return Regex.IsMatch(ipAddress, @"^\d{1,3}(\.\d{1,3}){3}$") &&
            ipAddress.Split('.').SingleOrDefault(s => int.Parse(s) > 255) == null;
    }

其他答案要么允许IPv6,要么允许输入“1.-0.1.1”。

答案 5 :(得分:2)

ipString中的部分数量(每个部分用句点分隔)决定了IP地址的构造方式。单部分地址直接存储在网络地址中。两部分地址,便于指定A类地址,将前导部分放在网络地址的最右边三个字节的第一个字节和尾部。三部分地址,便于指定B类地址,将第一部分放在第一个字节中,第二部分放在第二个字节中,最后部分放在网络地址的最右边两个字节中。例如:

零件数量和示例ipString  IP地址的IPv4地址

1 - “65536”  0.0.255.255

2 - “20.2”  20.0.0.2

2 - “20.65535”  20.0.255.255

3 - “128.1.2”  128.1.0.2

您可能需要参考MSDN文档 http://msdn.microsoft.com/en-us/library/system.net.ipaddress.parse.aspx

您最好的选择是IPAddress.ToString()或正则表达式。

答案 6 :(得分:1)

是的,这些是有效的地址。有关详细信息,请参阅http://en.wikipedia.org/wiki/IPv4#Address_representations

答案 7 :(得分:1)

尽管这个问题在两年前得到了解答,但我认为提出我今天在寻找同样的事情时想出的问题是相关的,在找到这个页面之后我决定我太懒了进行验证。

如果通过FormTextBox接受信息,则最好使用MaskedTextBox。您可以强制用户以IP地址格式输入信息,而不必自己进行猜测。

用于此类验证的掩码是990.990.990.990,其中OptionalNumber, OptionalNumber, MandatoryNumber表示1.1.1.110.10.10.10123.123.123.123都是有效的IP地址格式。这些掩码与Microsoft在Access中使用的格式相同。

答案 8 :(得分:0)

这是有道理的,因为65536等于0x00010000或0.1.0.0。我猜TryParse也会接受十六进制数字。无论如何,我认为你不想接受普通用户的这样的价值,但我想这取决于最终用户。

答案 9 :(得分:0)

以下代码使用正则表达式,由 Roshe

建议
        string txt = textBox1.Text;

        string ValidIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9‌​]{2}|2[0-4][0-9]|25[0-5])$";    // IP validation 

        Regex r = new Regex(ValidIpAddressRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Match m = r.Match(txt);

        if (!m.Success)
        {
          //Not a valid IP
        }

        else
        {


          //A valid IP

        }