web-dev-qa-db-ja.com

IPアドレスを検証する最良の方法は何ですか?

パラメーターのIPアドレスを検証する方法があります。全体として開発が初めてなので、これを行うより良い方法があるかどうか知りたいです。

/// <summary>
/// Check IP Address, will accept 0.0.0.0 as a valid IP
/// </summary>
/// <param name="strIP"></param>
/// <returns></returns>
public Boolean CheckIPValid(String strIP)
{
    //  Split string by ".", check that array length is 3
    char chrFullStop = '.';
    string[] arrOctets = strIP.Split(chrFullStop);
    if (arrOctets.Length != 4)
    {
        return false;
    }
    //  Check each substring checking that the int value is less than 255 and that is char[] length is !> 2
    Int16 MAXVALUE = 255;
    Int32 temp; // Parse returns Int32
    foreach (String strOctet in arrOctets)
    {
        if (strOctet.Length > 3)
        {
            return false;
        }

        temp = int.Parse(strOctet);
        if (temp > MAXVALUE)
        {
            return false;
        }
    }
    return true;
}

その単純な(私はそれを行うことができます)が、トリックを行うようです。

37
Stephen Murby

limitationwith IPAddress.TryParse メソッドは、文字列を変換できるかどうかを検証することですIPアドレス。したがって、"5"などの文字列値が指定されている場合、"0.0.0.5"と見なされます。

IPv4を検証する別のアプローチは次のとおりです。

public bool ValidateIPv4(string ipString)
{
    if (String.IsNullOrWhiteSpace(ipString))
    {
        return false;
    }

    string[] splitValues = ipString.Split('.');
    if (splitValues.Length != 4)
    {
        return false;
    }

    byte tempForParsing;

    return splitValues.All(r => byte.TryParse(r, out tempForParsing));
}

次のようにテストできます。

List<string> ipAddresses = new List<string>
{
    "2",
    "1.2.3",
    "1.2.3.4",
    "255.256.267.300",
    "127.0.0.1",
};
foreach (var ip in ipAddresses)
{
    Console.WriteLine($"{ip} ==> {ValidateIPv4(ip)}");
}

出力は次のようになります。

2 ==> False
1.2.3 ==> False
1.2.3.4 ==> True
255.256.267.300 ==> False
127.0.0.1 ==> True

IPAddress.TryParseを使用することもできますが、制限があり、解析が正しく行われない可能性があります。

System.Net.IPAddress.TryParseメソッド

TryParseは、入力を正常に解析した場合にtrueを返しますが、結果のIPアドレスが有効なものであることを必ずしも意味しないことに注意してください。 この方法を使用してIPアドレスを検証しないでください。

しかし、これは少なくとも3つのドットを含む通常の文字列で機能します。何かのようなもの:

string addrString = "192.168.0.1";
IPAddress address;
if (IPAddress.TryParse(addrString, out address)) {
       //Valid IP, with address containing the IP
} else {
       //Invalid IP
}

IPAddress.TryParseを使用すると、3つのドットの存在を確認し、TryParseを次のように呼び出すことができます。

public static bool ValidateIPv4(string ipString)
{
    if (ipString.Count(c => c == '.') != 3) return false;
    IPAddress address;
    return IPAddress.TryParse(ipString, out address);
}
79
Habib
using System.Net;
public static bool CheckIPValid(string strIP)
{
    IPAddress result = null;
    return
        !String.IsNullOrEmpty(strIP) &&
        IPAddress.TryParse(strIP, out result);
}

これで完了です

編集1

例外がスローされるのを防ぐための追加のチェックを追加しました(これはコストがかかります)。 PSそれはユニコードを処理しません。

Edit 2

@StephenMurby IPAddress.TryParseは、文字列の解析に成功した場合、trueを返します。メソッドの documentation をチェックすると、2つのケースで例外がスローされます。

  1. ストリングはヌルです。
  2. 文字列にはUnicode文字が含まれています。

例外をスローするかfalseを返すかを決定(設計上の決定)するのはユーザー次第です。解析に関しては、一般的に例外ではなくfalseを返すことを好みます(これは入力であり、正しいとは限りません)。

Returnステートメントを分解して、私は言っています、

  1. 文字列はnullではありません(とにかく解析されない空でもありません)[〜#〜] and [〜#〜]
  2. IPアドレスは正しく解析されます。

C#のブール式は 遅延評価 であるため、CLRはnullまたは空の場合、文字列の解析も試行しません。

行方不明の場合、次のようなことができます

if (IP.TryParse(strIP, out result)
{
    return true;
}

しかし、あなたが本当にしていることは、何かが真実である場合、真実を返すことです。式をすぐに返すのが簡単です。

13
M Afifi

IPAddress.Parse または IPAddress.TryParse を使用してはいけない理由

IPAddress.Parse(stringVarialbeContainingIP)
5
Adil

フレームワークはIPAddressクラスを提供し、このクラスはParseおよびTryParseメソッドを提供します。

// myAddress is a System.Net.IPAddress instance
if (System.Net.IPAddress.TryParse(strIP , out myAddress)) 
    // IP is valid
else
    // IP isn't valid
4
Alex

最高の正規表現ソリューション:

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

C#

Regex.IsMatch(value, "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")
4
GGO

IPAddressクラスを使用せず、バイトに対して検証することなく、Int <256アプローチよりもはるかに優れています。

    public Boolean CheckIPValid(String strIP)
    {
        //  Split string by ".", check that array length is 4
        string[] arrOctets = strIP.Split('.');
        if (arrOctets.Length != 4)
            return false;

        //Check each substring checking that parses to byte
        byte obyte = 0;
        foreach (string strOctet in arrOctets)
            if (!byte.TryParse(strOctet, out obyte)) 
                return false;

        return true;
    }
4

誰も正規表現ソリューションを提供していないことに驚いた。必要なのは、System.Text.RegularExpressionsを含めることだけです。実際のコードとこの例の両方で読みやすくするために、常に正規表現パターンを文字列配列にまとめてから結合します。

        // Any IP Address
        var Value = "192.168.0.55"; 
        var Pattern = new string[]
        {
            "^",                                            // Start of string
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.",    // Between 000 and 255 and "."
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.",
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.",
            @"([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])",      // Same as before, no period
            "$",                                            // End of string
        };

        // Evaluates to true 
        var Match = Regex.IsMatch(Value, string.Join(string.Empty, Pattern));
2
Free Radical

Ipv4またはipv6のように処理できます。

    public static string CheckIPValid(string strIP)
    {
        //IPAddress result = null;
        //return !String.IsNullOrEmpty(strIP) && IPAddress.TryParse(strIP, out result);
        IPAddress address;
        if (IPAddress.TryParse(strIP, out address))
        {
            switch (address.AddressFamily)
            {
                case System.Net.Sockets.AddressFamily.InterNetwork:
                    // we have IPv4
                    return "ipv4";
                //break;
                case System.Net.Sockets.AddressFamily.InterNetworkV6:
                    // we have IPv6
                    return "ipv6";
                //break;
                default:
                    // umm... yeah... I'm going to need to take your red packet and...
                    return null;
                    //break;
            }
        }
        return null;
    }
1
Yanga

有効かどうかだけを確認したい場合は、次のようにします。

bool isValid = IPAddress.TryParse(stringIP, out IPAddress _);

これが255を超えていて、ドットがある場合でも有効になるため、チェックする必要はありません。

0
Meroz

これで試してください:

private bool IsValidIP(String ip)
    {
        try
        {
            if (ip == null || ip.Length == 0)
            {
                return false;
            }

            String[] parts = ip.Split(new[] { "." }, StringSplitOptions.None);
            if (parts.Length != 4)
            {
                return false;
            }

            foreach (String s in parts)
            {
                int i = Int32.Parse(s);
                if ((i < 0) || (i > 255))
                {
                    return false;
                }
            }
            if (ip.EndsWith("."))
            {
                return false;
            }

            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }
0
Musculaa