Як визначити, чи рядок є допустимою адресою IPv4 або IPv6 у C #?


75

Я знаю, що регулярний вираз небезпечний для перевірки IP-адрес через різні форми, які може мати IP-адреса.

Я бачив подібні запитання щодо C та C ++, і вони були вирішені за допомогою функції, яка не існує в C # inet_ntop ()

Рішення .NET, які я знайшов, обробляють лише стандартну форму "ddd.ddd.ddd.ddd". Будь-які пропозиції?

Відповіді:


150

Ви можете використовувати це, щоб спробувати проаналізувати його:

 IPAddress.TryParse

Потім перевірте AddressFamilyякий

Повертає System.Net.Sockets.AddressFamily.InterNetwork для IPv4 або System.Net.Sockets.AddressFamily.InterNetworkV6 для IPv6.

EDIT: деякий зразок коду. змінити за бажанням:

    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;
        }
    }

4
Нема проблем. Як ви знаєте, BCL масивний. Я намагаюся читати його раз у раз, щоб просто подивитися, що там.
Еріх Мірабаль,

2
Цей метод повертає дійсну адресу IP4, навіть якщо введене користувачем значення "192.169.1".
Александру Діку

3
Так, тому що це правильна адреса IP і саме те , що оригінальний Аскер означає узгодження з допомогою регулярних виразів небезпечно ... Дивіться цей пост stackoverflow.com/questions/12566664 / ... для того, як TryParse роботи
claudekennilol

1
Тільки примітка: під час запуску на localhost адреса, з HttpContext.Current.Request.UserHostAddressякої повертається , успішно аналізується як InterNetworkV6адреса (адреса, про яку йдеться, призначена ::1для мене, що працює під керуванням IIS Express у Windows 10). Можливо, це не сильно вплине, оскільки це річ з місцевим хостом, але я хотів, щоб люди знали.
Doctor Blue

32

Просто попередження про використання System.Net.IpAddress.TryParse():

Якщо ви передасте йому рядок, що містить ціле число (наприклад, "3"), функція TryParse перетворить його на "0.0.0.3" і, отже, на дійсну адресу InterNetworkV4. Отже, щонайменше, переформатований "0.0.0.3" слід повернути користувацькій програмі, щоб користувач знав, як інтерпретувались їх введення.


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

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

Якщо isValidIpце правда, ви можете перевірити, ipAddress.AddressFamilyчи це IPv4 або IPv6. Це AddressFamily.InterNetworkдля IPv4 та AddressFamily.InterNetworkV6для IPv6.


7

Ви можете перевірити System.Uri.CheckHostName (значення) , що повертається Unknown, Dns, IPv4,IPv6 .

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

2
Цей метод повертає дійсну адресу IP4, навіть якщо введене користувачем значення "192.169.1". Без останнього набору мережевої адреси.
Александру Діку,

2
Добре, тому що це дійсна IP-адреса.
Фарилон

4

Якщо ви не хочете аналізувати кожне ціле число, а лише IP-адреси, просто перевірте .наявність IPv4 та :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;
                }
            }
        }

1

Ви можете використовувати властивість IPAddress.GetAddressBytes (). Length

        IPAddress someIP;

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

Я думаю, це повинно працювати


1

Мені підходить комбінація тестів, застосованих до рядка або IPAddress ..

        /// <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;
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.