Проверить действительный адрес IPv4 в Java

Я использую пакет 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 ...


person AngelsandDemons    schedule 26.09.2011    source источник
comment
oracle.com/technetwork/java/faq-sun-packages- 142232.html   -  person BalusC    schedule 26.09.2011
comment
Да ... Я прошел по этой ссылке ... Но я не думаю, что они предоставили какой-либо новый выпуск для этого пакета или какой-либо из упомянутых методов устарел ... Я думаю, для этих проверок лучше использовать общую библиотеку apache. .....Какие-либо предложения..?   -  person AngelsandDemons    schedule 26.09.2011
comment
возможный дубликат Подтвердить IP-адрес   -  person Jason C    schedule 24.03.2014


Ответы (6)


Есть причина, по которой вы получаете "действительный" результат: 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_presentations, чтобы узнать больше.

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

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

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

person cHao    schedule 26.09.2011
comment
Следует отметить, что правила для адресов IPv6 намного строже. - person Joachim Sauer; 26.09.2011
comment
@Joachim: Отметил. Хотя, по правде говоря, я очень сомневаюсь, что слишком много людей будут пытаться проверять адреса IPv6 в ближайшее время :) - person cHao; 26.09.2011
comment
это означает только то, что многие люди будут использовать непроверенные адреса IPv6. Они приходят, и если ваше программное обеспечение их не поддерживает, вы останетесь позади. - person Joachim Sauer; 26.09.2011
comment
Я слышал о приближении IPv6 ›10 лет. Все еще жду. Я даже не могу заставить IPV6 работать без туннельного брокера. :П - person cHao; 26.09.2011
comment
Спасибо, cHao .... Мне лучше использовать Apache Validator для проверки IPV4-адреса .... Я не люблю использовать сопоставление с образцом и регулярное выражение .... - person AngelsandDemons; 26.09.2011
comment
@chao: Исходный текст: (Если открыть браузер и перейти к 1249739112 или даже 74.125.33128, например, откроется главная страница Google.) - person cHao; 24.09.2012

Ознакомьтесь с Guava http://docs.guava-libraries/ класс, который содержит статические служебные методы для работы с IP-адреса. (Насколько я понимаю, за кулисами он использует класс sun.net.util.IPAddressUtil.)

System.out.println(InetAddresses.isInetAddress("400")); // false
person Kohányi Róbert    schedule 26.09.2011
comment
Да, это отлично работает для адресов IPv4. Однако я хотел бы принять адрес IPv6 из командной строки. Для проверки IPv6-адресов я вижу здесь только метод isIsatapAddress (Inet6Address ip). Не уверен, как получить объект Inet6address из строки ... - person Thomas; 06.06.2012
comment
@Thomas Код в моем ответе только тестирует IP-адреса. Оформить заказ этот метод. - person Kohányi Róbert; 06.06.2012

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

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

который имеет проверку IP-адреса.

person MeBigFatGuy    schedule 26.09.2011
comment
Это был первый пакет, который я увидел при просмотре проверки IPV4. Однако я не хотел использовать его изначально, но, похоже, другого варианта нет ... - person AngelsandDemons; 26.09.2011

Если вы хотите проверить, является ли строка допустимым представлением IP-адреса, исходный код http://www.docjar.com/html/api/org/apache/http/conn/util/InetAddressUtils.java.html использует эти регулярные выражения:

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})*)?)$");
person grebulon    schedule 07.04.2015

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

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

что подходило для простых проверок.

person Johntor    schedule 23.01.2014

Эта строка представляет собой строковый формат 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-адрес менее чем с четырьмя сегментами

person Sean F    schedule 19.10.2016