[.NET]驗證字串是否為合法的IP Address

要如何驗證字串是否為合法的IP Address,並取出該IP Address?

在論壇上看到「從字串中找出IP位子」,而網路上有人說可以使用Regex或是IPAddress來做!

即然IPAddress有提供TryParse就使用它來處理吧! 如下,


private string GetValidatedIP(string ipStr)
{
	string validatedIP = string.Empty;
	IPAddress ip;
	if (IPAddress.TryParse(ipStr, out ip))
	{
		validatedIP = ip.ToString();
	}
	return validatedIP;
}

 

所以我們用以下的程式碼來測試一下,


string ipV4 = @"127.0.0.1";
string validatedIPV4 = GetValidatedIPEx(ipV4);
Console.WriteLine("驗証後的IP v4:{0}", validatedIPV4);

string ipV6 = @"fe80::64f6:1658:a0ba:65d1%12";
string validatedIPV6 = GetValidatedIPEx(ipV6);
Console.WriteLine("驗証後的IP v6:{0}", validatedIPV6);

string illegalIp = @"256.0.0.1";
string validatedIllegalIp = GetValidatedIPEx(illegalIp);
Console.WriteLine("驗証後的IP illegalIp:{0}", validatedIllegalIp);

//如果ip + Port的話,使用IPAddress.TryParse會無法解析成功
string ipV4AndPort = @"127.0.0.1:8080";
string validatedIPV4AndPort = GetValidatedIPEx(ipV4AndPort);
Console.WriteLine("驗証後的IP v4AndPort:{0}", validatedIPV4AndPort);

string ipV6AndPort = @"fe80::64f6:1658:a0ba:65d1%12";
string validatedIPV6AndPort = GetValidatedIPEx(ipV6AndPort);
Console.WriteLine("驗証後的IP v6AndPort:{0}", validatedIPV6AndPort);

image

 

從上面可以發現,IPv4或IPv6都可以順利的Parse出來。

但如果是IP + Port的話,它就不認得了!

所以可以參考「IPAddress.Parse() using port on IPv4」,先使用Uri來TryCreate後,再使用IPAddress來TryParse。

所以新增一個驗証的Method如下,


private string GetValidatedIPEx(string ipStr)
{
	string validatedIP = string.Empty;
	//如果ip + Port的話,使用IPAddress.TryParse會無法解析成功
	//所以加入Uri來判斷看看
	Uri url;
	IPAddress ip;
	if (Uri.TryCreate(string.Format("http://{0}", ipStr), UriKind.Absolute, out url))
	{
		if (IPAddress.TryParse(url.Host, out ip))
		{
			//合法的IP
			validatedIP = ip.ToString();
		}
	}
	else
	{
		//可能是ipV6,所以用Uri.CheckHostName來處理
		var chkHostInfo = Uri.CheckHostName(ipStr);
		if (chkHostInfo == UriHostNameType.IPv6)
		{
			//V6才進來處理
			if (IPAddress.TryParse(ipStr, out ip))
			{
				validatedIP = ip.ToString();
			}
			else
			{
				//後面有Port Num,所以再進行處理
				int colonPos = ipStr.LastIndexOf(":");
				if (colonPos > 0)
				{
					string tempIp = ipStr.Substring(0, colonPos - 1);
					if (IPAddress.TryParse(tempIp, out ip))
					{
						validatedIP = ip.ToString();
					}
				}
			}
		}
	}
	return validatedIP;
}

 

再用以下的程式碼來測試一下,


string ipV4 = @"127.0.0.1";
string validatedIPV4 = GetValidatedIPEx(ipV4);
Console.WriteLine("驗証後的IP v4:{0}", validatedIPV4);

string ipV6 = @"fe80::64f6:1658:a0ba:65d1%12";
string validatedIPV6 = GetValidatedIPEx(ipV6);
Console.WriteLine("驗証後的IP v6:{0}", validatedIPV6);

string illegalIp = @"256.0.0.1";
string validatedIllegalIp = GetValidatedIPEx(illegalIp);
Console.WriteLine("驗証後的IP illegalIp:{0}", validatedIllegalIp);

//如果ip + Port的話,使用IPAddress.TryParse會無法解析成功
string ipV4AndPort = @"127.0.0.1:8080";
string validatedIPV4AndPort = GetValidatedIPEx(ipV4AndPort);
Console.WriteLine("驗証後的IP v4AndPort:{0}", validatedIPV4AndPort);

string ipV6AndPort = @"fe80::64f6:1658:a0ba:65d1%12";
string validatedIPV6AndPort = GetValidatedIPEx(ipV6AndPort);
Console.WriteLine("驗証後的IP v6AndPort:{0}", validatedIPV6AndPort);

image

 

從以上的測試,可以發現,目前不管理IPV4 or IPV6都可以正確的被Parse出來了!

如果各位先進有其他的方式,也請分享出來,謝謝!

 

參考資料

IPAddress.Parse() using port on IPv4

IPAddress.TryParse 方法

Regex 類別

Uri 類別

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^