如何确定一个字符串是一个有效的 IPv4或 IPv6地址在 C # ?

我知道 regex 是用于验证 IP 地址的 很危险,因为 IP 地址可以采用不同的形式。

我见过 C 和 C + + 的类似问题,这些问题都是用 C # Inet _ ntop ()中不存在的函数解决的

我找到的.NET 解决方案只能处理标准的“ ddd.ddd.ddd.dddd”表单。有什么建议吗?

105445 次浏览

You can use this to try and parse it:

 IPAddress.TryParse

Then check AddressFamily which

Returns System.Net.Sockets.AddressFamily.InterNetwork for IPv4 or System.Net.Sockets.AddressFamily.InterNetworkV6 for IPv6.

EDIT: some sample code. change as desired:

    string input = "your IP address goes here";


IPAddress address;
if (IPAddress.TryParse(input, out address))
{
switch (address.AddressFamily)
{
case System.Net.Sockets.AddressFamily.InterNetwork:
// we have IPv4
break;
case System.Net.Sockets.AddressFamily.InterNetworkV6:
// we have IPv6
break;
default:
// umm... yeah... I'm going to need to take your red packet and...
break;
}
}
string myIpString = "192.168.2.1";
System.Net.IPAddress ipAddress = null;


bool isValidIp = System.Net.IPAddress.TryParse(myIpString, out ipAddress);

If isValidIp is true, you can check ipAddress.AddressFamily to determine if it's IPv4 or IPv6. It's AddressFamily.InterNetwork for IPv4 and AddressFamily.InterNetworkV6 for IPv6.

Just a warning about using System.Net.IpAddress.TryParse():

If you pass it an string containing an integer (e.g. "3") the TryParse function will convert it to "0.0.0.3" and, therefore, a valid InterNetworkV4 address. So, at the very least, the reformatted "0.0.0.3" should be returned to the user application so the user knows how their input was interpreted.

You could check out System.Uri.CheckHostName( value ) that returns ABC0 , ABC1, ABC2, IPv6.

if( Uri.CheckHostName( value ) != UriHostNameType.Unknown)
//then 'value' is a valid IP address or hostname

You may use the IPAddress.GetAddressBytes().Length property

        IPAddress someIP;


if (someIP.GetAddressBytes().Length == 4)
{
// IPV4
}
else if (someIP.GetAddressBytes().Length == 16)
{
// IPV6
}
else
{
// Unknown
}

I guess should work

If you don't want to parse every integer, but only IPs, just check . for IPv4 and : for IPv6.

        if (input.Contains(".") || input.Contains(":"))
{
IPAddress address;
if (IPAddress.TryParse(input, out address))
{
switch (address.AddressFamily)
{
case AddressFamily.InterNetwork:
return Ip4Address;
case AddressFamily.InterNetworkV6:
return Ip6Address;
}
}
}

A combination of tests applied to a string or IPAddress, works for me..

        /// <summary>
/// Test string for valid ip address format
/// </summary>
///
/// <param name="Address">The ip address string</param>
///
/// <returns>Returns true if address is a valid format</returns>
public static bool IsValidIP(IPAddress Ip)
{
byte[] addBytes = Ip.GetAddressBytes();


switch (Ip.AddressFamily)
{
case AddressFamily.InterNetwork:
if (addBytes.Length == 4)
return true;
break;
case AddressFamily.InterNetworkV6:
if (addBytes.Length == 16)
return true;
break;
default:
break;
}


return false;
}


/// <summary>
/// Test string for valid ip address format
/// </summary>
///
/// <param name="Address">The ip address string</param>
///
/// <returns>Returns true if address is a valid format</returns>
public static bool IsValidIP(string Address)
{
IPAddress ip;
if (IPAddress.TryParse(Address, out ip))
{
switch (ip.AddressFamily)
{
case System.Net.Sockets.AddressFamily.InterNetwork:
if (Address.Length > 6 && Address.Contains("."))
{
string[] s = Address.Split('.');
if (s.Length == 4 && s[0].Length > 0 &&  s[1].Length > 0 &&  s[2].Length > 0 &&  s[3].Length > 0)
return true;
}
break;
case System.Net.Sockets.AddressFamily.InterNetworkV6:
if (Address.Contains(":") && Address.Length > 15)
return true;
break;
default:
break;
}
}


return false;
}