Библиотека Java для преобразования длинного адреса IPv6 в сжатую форму - PullRequest
5 голосов
/ 21 сентября 2010

Я хотел бы знать, есть ли библиотека, которую я могу использовать для преобразования представления длинного адреса IPv6 (например, 2002: 9876: 57AB: 0000: 0000: 0000: 0000: 0001) в сжатый IPv6 форма (в данном случае: 2002: 9876: 57AB :: 1).

Мне не удалось найти такую ​​библиотеку. Эта библиотека не должна использовать какие-либо IP Api, сетевое соединение не должно быть установлено.

Я уже пробовал

return Inet6Address.getByName(longAdress).toString();

но это просто заменяет 4 нуля на 1 ноль (в данном случае 2002: 9876: 57AB: 0: 0: 0: 0: 1).

есть предложения?

Ответы [ 4 ]

5 голосов
/ 26 марта 2013

java-ipv6 - очень приличная библиотека для этого.Он также хорошо обрабатывает диапазоны адресов.

3 голосов
/ 21 сентября 2010
public class Ipv6AddressCompressor {
    public static String getCompressedAddress(String longAddress) throws UnknownHostException {
        longAddress = Inet6Address.getByName(longAddress).getHostAddress();
        return longAddress.replaceFirst("(^|:)(0+(:|$)){2,8}", "::");
    }
}

Это должно защитить вас от недопустимых адресов (генерирует исключение UnknownHostException) и будет правильно сжимать конечные адреса ipv4 (т.е. 0: 0: 0: 0: 0: 0: 255.255.255.255 -> :: FFFF: FFFF). Это также защитит от уже сжатых адресов.

1 голос
/ 05 марта 2017

Библиотека Java с открытым исходным кодом IPAddress может выполнять разбор IP-адресов и создавать различные строки.Отказ от ответственности: я являюсь руководителем проекта этой библиотеки.

Пример кода:

    String ipv6 = "2002:9876:57AB:0000:0000:0000:0000:0001";
    try {
        IPAddressString str = new IPAddressString(ipv6);
        IPAddress addr = str.toAddress();
        String compressed = addr.toCompressedString();
        System.out.println(compressed); //
    } catch(IPAddressStringException e) {
        //e.getMessage has validation error
    }

вывод:

2002:9876:57ab::1
0 голосов
/ 09 июля 2011

Вы можете попробовать этот код.Вероятно, он будет работать лучше, чем эквивалент регулярного выражения (не то, чтобы я его тестировал или что-то в этом роде).Он также довольно хорошо протестирован.

Обратите внимание, что вам нужно будет использовать числовое представление (в byte[]) IP-адреса.Чтобы получить его, вы можете либо сделать InetAddress.getByName(ip).getAddress(), если вам нужно разрешить имена хостов, либо использовать утилиту класса Sun IPAddressUtil.textToNumericFormatV6(ip) для анализа IP-адреса без разрешения хоста.

private static final char[] ipv6conseqZeroFiller = { ':', ':' };
private static final char ipv6hextetSeparator = ':';

/*
 * Convert numeric IPv6 to compressed format, where
 * the longest sequence of 0's (with 2 or more 0's) is replaced with "::"
 */
public static String ipv6toCompressedForm(byte[] src) {
    assert src.length == 16;
    //Find the longest sequence of 0's 
    int cmprHextet = -1; //start of compressed region (hextet index)
    int cmprSize = 0; //length of compressed region
    for (int hextet = 0; hextet < 8;) {
        int curByte = hextet * 2;
        int size = 0;
        while (curByte < src.length && src[curByte] == 0
                && src[curByte + 1] == 0) {
            curByte += 2;
            size++;
        }
        if (size > cmprSize) {
            cmprHextet = hextet;
            cmprSize = size;
        }
        hextet = (curByte / 2) + 1;
    }
    if (cmprHextet == -1 || cmprSize < 2) {
        //No compression can be applied
        return ipv6toStr(src);
    }
    StringBuilder sb = new StringBuilder(39);
    ipv6toStr(sb, src, 0, cmprHextet);
    sb.append(ipv6conseqZeroFiller);
    ipv6toStr(sb, src, cmprHextet + cmprSize, 8);
    return sb.toString();
}

/*
 * Convert numeric IPv6 to standard (non-compressed) format.
 *
 * Borrowed from Inet6Address.java #numericToTextFormat(byte[])
 * Changed StringBuffer -> StringBuilder and ":" -> ':' for performance.
 */
public static String ipv6toStr(byte[] src) {
    assert src.length == 16;
    StringBuilder sb = new StringBuilder(39);
    ipv6toStr(sb, src, 0, 8);
    return sb.toString();
}

private static final void ipv6toStr(StringBuilder sb, byte[] src,
        int fromHextet, int toHextet) {
    for (int i = fromHextet; i < toHextet; i++) {
        sb.append(Integer.toHexString(((src[i << 1] << 8) & 0xff00)
                | (src[(i << 1) + 1] & 0xff)));
        if (i < toHextet - 1) {
            sb.append(ipv6hextetSeparator);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...