Проверка IPv6 - PullRequest
       36

Проверка IPv6

10 голосов
/ 11 мая 2011

Я использовал IPAddressUtil.isIPv6LiteralAddress (ipAddress) метод для проверки IPv6, но этот метод не работает для формата ipv6-address / prefix-length (формат указан в RFC 4291 раздел 2.3) IPV6.

Может кто-нибудь знать какие-либо валидаторы, которые проверяют формат "ipv6-address / prefix-length"?

Юридические представления IPV6

  1. ABCD: EF01: 2345:6789: ABCD: EF01: 2345: 6789
  2. 2001: DB8: 0: 0: 8: 800: 200C: 417A
  3. FF01: 0: 0: 0: 0: 0: 0:101
  4. 0: 0: 0: 0: 0: 0: 0: 0: 1
  5. 0: 0: 0: 0: 0: 0: 0: 0
  6. 2001: DB8 :: 8: 800: 200C: 417A
  7. FF01 :: 101
  8. :: 1
  9. ::
  10. 0: 0: 0:0: 0: 0: 13.1.68.3
  11. 0: 0: 0: 0: 0: FFFF: 129.144.52.38
  12. :: 13.1.68.3
  13. FFFF: 129.144.52.38
  14. 2001: 0DB8: 0000: CD30: 0000: 0000: 0000: 0000/60
  15. 2001: 0DB8 :: CD30: 0: 0: 0: 0/60
  16. 2001: 0DB8: 0: CD30 :: / 60

НЕ юридические представления IPV6

  1. 2001: 0DB8: 0: CD3/ 60
  2. 2001: 0DB8 :: CD30 / 60
  3. 2001: 0DB8 :: CD3 / 60

Ответы [ 6 ]

4 голосов
/ 18 января 2013

Вы можете использовать библиотеку Guava, в частности, с помощью класса com.google.common.net.InetAddresses, вызывая isInetAddress () .

2 голосов
/ 11 мая 2011

Посмотрите, работает ли это:

try {
    if (subjectString.matches(
        "(?ix)\\A(?:                                                  # Anchor address\n" +
        " (?:  # Mixed\n" +
        "  (?:[A-F0-9]{1,4}:){6}                                # Non-compressed\n" +
        " |(?=(?:[A-F0-9]{0,4}:){2,6}                           # Compressed with 2 to 6 colons\n" +
        "     (?:[0-9]{1,3}\\.){3}[0-9]{1,3}                     #    and 4 bytes\n" +
        "     \\z)                                               #    and anchored\n" +
        "  (([0-9A-F]{1,4}:){1,5}|:)((:[0-9A-F]{1,4}){1,5}:|:)  #    and at most 1 double colon\n" +
        " |::(?:[A-F0-9]{1,4}:){5}                              # Compressed with 7 colons and 5 numbers\n" +
        " )\n" +
        " (?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}  # 255.255.255.\n" +
        " (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])           # 255\n" +
        "|     # Standard\n" +
        " (?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}                    # Standard\n" +
        "|     # Compressed\n" +
        " (?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4}               # Compressed with at most 7 colons\n" +
        "    \\z)                                                #    and anchored\n" +
        " (([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:)    #    and at most 1 double colon\n" +
        "|(?:[A-F0-9]{1,4}:){7}:|:(:[A-F0-9]{1,4}){7}           # Compressed with 8 colons\n" +
        ")/[A-F0-9]{0,4}\\z                                                    # Anchor address")) 
        {
        // String matched entirely
    } else {
        // Match attempt failed
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

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

Предполагалось, что это будетJava, поэтому он должен скомпилироваться, я предполагаю, что / 60 может быть между диапазонами 0000 и FFFF, которые вы можете изменить в этой последней части.

/ [A-F0-9] {0,4} - это то, что ядобавлен в регулярное выражение в соответствии с вашим примером.

0 голосов
/ 07 апреля 2019

Библиотека Java IPAddress поддерживает синтаксический анализ как подсетей CIDR IPv4, так и IPv6 (т. Е. Формат адреса / префикса) полиморфным способом. Отказ от ответственности: я менеджер проекта.

Следующий пример является примером кода для проверки:

static void parse(String str) {
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         IPAddress hostAddr = addrString.toHostAddress();
         Integer prefix = addr.getNetworkPrefixLength();
         if(prefix == null) {
             System.out.println(addr + " has no prefix length"); 
         } else {
             System.out.println(addr + " has host address " + hostAddr + " and prefix length " + prefix);
         }
    } catch(AddressStringException e) {
        System.out.println(addrString + " is invalid: " + e.getMessage());
    }
}

Используя примеры, представленные в вопросе, результат вышеприведенного метода:

abcd:ef01:2345:6789:abcd:ef01:2345:6789 has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
::d01:4403 has no prefix length
::ffff:8190:3426 has no prefix length
::d01:4403 has no prefix length
FFFF:129.144.52.38 is invalid: FFFF:129.144.52.38 IP Address error: address has too few segments
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:0DB8:0:CD3/60 is invalid: 2001:0DB8:0:CD3/60 IP Address error: address has too few segments
2001:db8::cd30/60 has host address 2001:db8::cd30 and prefix length 60
2001:db8::cd3/60 has host address 2001:db8::cd3 and prefix length 60

Как видите, вопрос был неверным о том, что FFFF: 129.144.52.38 является действительным, а о 2001: db8 :: cd30 / 60 и 2001: db8 :: cd3 / 60 - недействительным. Первый из них будет действительным, если он будет :: FFFF: 129.144.52.38

0 голосов
/ 13 апреля 2015

Я пробовал ниже регулярное выражение в Java, и это работало для IPV4 и IPV6

public class Utilities {
private static Pattern VALID_IPV4_PATTERN = null;
private static Pattern VALID_IPV6_PATTERN = null;
private static final String ipv4Pattern = "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])";
private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}";

static {
try {
  VALID_IPV4_PATTERN = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE);
  VALID_IPV6_PATTERN = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE);
   } catch (PatternSyntaxException e) {
  //logger.severe("Unable to compile pattern", e);
 }
}

 /**
 * Determine if the given string is a valid IPv4 or IPv6 address.  This method
 * uses pattern matching to see if the given string could be a valid IP address.
 *
 * @param ipAddress A string that is to be examined to verify whether or not
 * it could be a valid IP address.
 * @return <code>true</code> if the string is a value that is a valid IP address,
 *  <code>false</code> otherwise.
 */
 public static boolean isIpAddress(String ipAddress) {

Matcher m1 = Utilities.VALID_IPV4_PATTERN.matcher(ipAddress);
if (m1.matches()) {
  return true;
}
Matcher m2 = Utilities.VALID_IPV6_PATTERN.matcher(ipAddress);
return m2.matches();
  }


}
0 голосов
/ 14 мая 2014

Моя идея состоит в том, чтобы разделить его на две части: адрес префикса и префикс len.

1. подтвердить адрес префикса, используйте регулярное выражение some для проверки адреса IPv6
2. проверьте префикс len, который должен быть целым числом
3. адрес префикса может иметь только ':' меньше, чем результат prefix len divided by 16
4. необходимо учитывать и другую логику, оставьте TODO здесь, извините: (

  private int validateIPv6AddrWithPrefix(String address) {
        int occurCount = 0;
        for(char c : address) {
            if(c=='/'){
                occurCount++;
            }
        }
        if(occurCount != 1){
         //not good, to much / character
            return -1;
        }
        /* 2nd element should be an integer */
        String[] ss = pool.getAddress().split("/");
        Integer prefixLen = null;
        try{
            prefixLen = Integer.valueOf(ss[1]);
                    // TODO validate the prefix range(1, 128)

        }catch(NumberFormatException e) {
            /* not a Integer */
            return -1;
        }
        /* 1st element should be ipv6 address */
        if(!IPaddrUtilities.isIPv6Address(ss[0])) {
            return -1;
        }
        /* validate ':' character logic */
        occurCount = 0;
        for(char c : ss[0].toCharArray()){
            if(c==':') {
                occurCount++;
            }
        }
        if(occurCount >= prefixLen/16) {
            // to much ':' character
            return -1;
        }
        return 0;
    }
0 голосов
/ 19 ноября 2013

Строго говоря, в разделе 2.3 описывается не представление адреса, а представление адреса префикс (даже префикс полной длины не совпадает с адресом).

Префикс IPv6-адреса представлен нотацией: ipv6-address / prefix-length, где ipv6-address - это IPv6-адрес в любой из нотаций, перечисленных в разделе 2.2.

Это означает, что вы можете спокойно игнорировать этот формат, если вам нужно проверить адреса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...