Wie kann festgestellt werden, ob eine Zeichenfolge eine gültige IPv4- oder IPv6-Adresse in C # ist?

75

Ich weiß, dass Regex für die Validierung von IP-Adressen gefährlich ist, da eine IP-Adresse unterschiedliche Formen annehmen kann.

Ich habe ähnliche Fragen für C und C ++ gesehen, und diese wurden mit einer Funktion gelöst, die in C # inet_ntop () nicht vorhanden ist.

Die .NET-Lösungen, die ich gefunden habe, verarbeiten nur das Standardformular "ddd.ddd.ddd.ddd". Irgendwelche Vorschläge?

Josh
quelle

Antworten:

150

Sie können dies verwenden, um zu versuchen, es zu analysieren:

 IPAddress.TryParse

Dann überprüfen Sie AddressFamilywelche

Gibt System.Net.Sockets.AddressFamily.InterNetwork für IPv4 oder System.Net.Sockets.AddressFamily.InterNetworkV6 für IPv6 zurück.

EDIT: einige Beispielcode. nach Wunsch ändern:

    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;
        }
    }
Erich Mirabal
quelle
4
Kein Problem. Die BCL ist massiv, wie Sie wissen. Ich versuche es von Zeit zu Zeit durchzulesen, nur um zu sehen, was da draußen ist.
Erich Mirabal
2
Diese Methode gibt eine gültige IP4-Adresse zurück, auch wenn die Benutzereingabe "192.169.1" lautet.
Alexandru Dicu
3
Ja, da dies eine gültige IP-Adresse ist und genau das ist, was der ursprüngliche Fragesteller mit dem Abgleichen über Regex gemeint hat, ist gefährlich ... In diesem Beitrag erfahren Sie, wie tryparse funktioniert
claudekennilol
1
Nur ein Hinweis: Bei der Ausführung auf localhost wird die zurückgegebene Adresse HttpContext.Current.Request.UserHostAddresserfolgreich als InterNetworkV6Adresse analysiert (die betreffende Adresse ist ::1für mich selbst, wenn IIS Express unter Windows 10 ausgeführt wird). Wahrscheinlich wird es nicht viel bewirken, da es sich um eine lokale Hostsache handelt, aber ich wollte, dass die Leute es wissen.
Doktor Blue
32

Nur eine Warnung zur Verwendung von System.Net.IpAddress.TryParse():

Wenn Sie ihm eine Zeichenfolge übergeben, die eine Ganzzahl enthält (z. B. "3"), konvertiert die TryParse-Funktion diese in "0.0.0.3" und daher in eine gültige InterNetworkV4-Adresse. Zumindest sollte das neu formatierte "0.0.0.3" an die Benutzeranwendung zurückgegeben werden, damit der Benutzer weiß, wie seine Eingabe interpretiert wurde.

Aaronster
quelle
16
string myIpString = "192.168.2.1";
System.Net.IPAddress ipAddress = null;

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

Wenn dies isValidIpzutrifft, können Sie überprüfen ipAddress.AddressFamily, ob es sich um IPv4 oder IPv6 handelt. Es ist AddressFamily.InterNetworkfür IPv4 und AddressFamily.InterNetworkV6für IPv6.

Tamas Czinege
quelle
7

Sie könnten überprüfen System.Uri.CheckHostName (Wert) , dass die Renditen Unknown, Dns, IPv4,IPv6 .

if( Uri.CheckHostName( value ) != UriHostNameType.Unknown)
    //then 'value' is a valid IP address or hostname
Daniel
quelle
2
Diese Methode gibt eine gültige IP4-Adresse zurück, auch wenn die Benutzereingabe "192.169.1" lautet. Ohne den letzten Satz von Netzadressen.
Alexandru Dicu
2
Gut, denn das ist eine gültige IP-Adresse.
Pharylon
4

Wenn Sie nicht jede Ganzzahl, sondern nur IPs analysieren möchten, suchen Sie einfach .nach IPv4 und :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;
                }
            }
        }
King_SaGo
quelle
1

Sie können die Eigenschaft IPAddress.GetAddressBytes (). Length verwenden

        IPAddress someIP;

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

Ich denke sollte funktionieren

Mc_Topaz
quelle
1

Eine Kombination von Tests, die auf einen String oder eine IPAddress angewendet werden, funktioniert für mich.

        /// <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;
    }
JGU
quelle