Проверьте действительный IPv4-адрес в Java - PullRequest
5 голосов
/ 26 сентября 2011

Я использую пакет sun.net.util.IPAddressUtil, чтобы проверить, содержит ли строка действительные адреса IPv4 и IPv6.

Фрагмент кода: -

String ipv4addr="200";

    if(IPAddressUtil.isIPv4LiteralAddress(ipv4addr))
    {
        System.out.println("valid ipv4 address");
    }
    else
    {
        System.out.println("not valid");

    }

Но для адресов, таких как 200 и 300, все еще говорят, что это действительный адрес IPv4, а это не так. Когда я использовал тот же пакет и проверил адрес IPV6, используя: -

String ipv6addr="200";

    if(IPAddressUtil.isIPv6LiteralAddress(ipv6addr))
    {
        System.out.println("valid ipv6 address");
    }
    else
    {
        System.out.println("not valid");

    }

Я получаю правильный результат. Тем не менее, кажется, что IPv4 не работает, или я использую его неправильно. Пожалуйста, ведите меня. Я не хочу использовать регулярное выражение для проверки IPv4 ...

Ответы [ 6 ]

23 голосов
/ 26 сентября 2011

Существует причина, по которой вы получаете «действительный» результат: 200 является действительным адресом IPv4.

Смотрите, для компьютера адрес IPv4 - это просто 32-битное число. Точки предназначены исключительно для нашего удобства, потому что мы, люди, сосем запоминание больших точных чисел. Но они не должны быть там; Существуют правила о том, как анализируется адрес, в зависимости от того, сколько его частей.

Когда адрес состоит из одного числа, он считается 32-разрядным числом, и каждый байт равен 8 битам этого числа. Если вы проанализируете "200" как IP-адрес, это будет эквивалентно 0.0.0.200. Аналогично, "2130706433" будет эквивалентно 127.0.0.1.

Существуют также стандарты для случаев, когда адрес состоит из двух частей, таких как 0,200 (первая часть - первый байт, а вторая часть - 24-разрядное число, представляющее остальные 3 байта) и даже 0,0.200 (первые два числа). являются байтами, последняя часть составляет 16 бит и занимает другие 2 байта). «Необычные» форматы остались со времен классов IP-адресов, но почти все программное обеспечение, которое должно анализировать их, поймет их. (Если вы откроете браузер и перейдете к http://1249739112* или даже http://74.125.33128*, например, откроется домашняя страница Google.)

* Смотрите комментарии для кликабельных ссылок. Спасибо, "ссылка валидатор". : P

Подробнее см. http://download.oracle.com/javase/6/docs/api/java/net/Inet4Address.html или http://www.perlmonks.org/?node_id=221512, или http://en.wikipedia.org/wiki/IPv4#Address_representations,.

Java также понимает эти форматы (как и .net, а также любую приличную ОС) и правильно анализирует адрес, содержит ли он 1, 2, 3 или 4 части.

Если вы хотите проверить, что потенциальный адрес действительно выглядит как «xxx.xxx.xxx.xxx», то вы, вероятно, захотите явно проверить это, используя шаблон или библиотеку проверки, которая учитывает 32- битовые числа как недействительные адреса (даже если они действительны). Но я бы не стал беспокоиться - если вы используете предоставленные функции поиска, вы можете принять адрес в любом стандартном формате, и он будет работать.

(Весь этот беспорядок меняется с IPv6; есть гораздо более строгий формат, и вы не можете просто ввести какое-то 36-значное число и ожидать, что он будет работать. Но платформа все еще знает, как анализировать адрес, и вы должны доверься этому.)

3 голосов
/ 26 сентября 2011

Извлечение Класс InetAddresses в Guava, который содержит статические служебные методы для работы с IP-адресами. (Насколько я понимаю, он использует класс sun.net.util.IPAddressUtil за кулисами.)

System.out.println(InetAddresses.isInetAddress("400")); // false
2 голосов
/ 26 сентября 2011

Не рекомендуется использовать внутренние "упакованные" "солнечные" классы, я бы попробовал использовать Validator Apache

http://commons.apache.org/validator/

с проверкой IP-адреса.

1 голос
/ 07 апреля 2015

Если вы хотите проверить, является ли строка допустимым представлением IP-адреса, исходный код org.apache.http.conn.util.InetAddressUtils использует следующие регулярные выражения:

IPV4_PATTERN = Pattern.compile(
    "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
IPV6_STD_PATTERN = Pattern.compile(
    "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile(
    "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$");
0 голосов
/ 19 октября 2016

Эта строка является форматом строки IPv4, который был первоначально введен утилитой aton_inet в BSD Unix и сохранился до сегодняшнего дня в различных вариантах Unix и Linux и в других местах.

https://linux.die.net/man/3/inet_aton

Библиотека Java IPAddress выполнит проверку, которая может быть настроена на поддержку форматов aton_inet или нет. Javadoc доступен по ссылке. Отказ от ответственности: я руководитель проекта.

Убедитесь, что адрес действителен, разрешите стиль inet_aton:

    String str = "200";
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         System.out.println("valid address: " + addr.toCanonicalString());
    } catch(IPAddressStringException e) {
        System.out.println(e.getMessage());
    }

Выход:

действительный адрес: 0.0.0.200

Убедитесь, что адрес действителен, не разрешайте стиль inet_aton:

    IPAddressStringParameters parameters = new       
      IPAddressStringParameters.Builder().allow_inet_aton(false).toParams();
    addrString = new IPAddressString(str, parameters);
    try {
         IPAddress addr = addrString.toAddress();
         System.out.println("valid address: " + addr.toCanonicalString());
    } catch(IPAddressStringException e) {
        System.out.println(e.getMessage());
    }

Выход:

200 Ошибка IP-адреса: опции не позволяют IPv4-адресам с менее чем четырьмя сегментами

0 голосов
/ 23 января 2014

После небольшого исследования у меня получилось что-то вроде этого

    public static boolean isValidIP4Address(String ipAddress) {
        if (ipAddress.matches("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$")) {
            String[] groups = ipAddress.split("\\.");

            for (int i = 0; i <= 3; i++) {
                String segment = groups[i];
                if (segment == null || segment.length() <= 0) {
                    return false;
                }

                int value = 0;
                try {
                    value = Integer.parseInt(segment);
                } catch (NumberFormatException e) {
                    return false;
                }
                if (value > 255) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

, которое подойдет для простых проверок.

...