用于将长 IPv6 地址转换为其压缩形式的 Java 库

问题描述 投票:0回答:5

我想知道是否有一个库可以用来将长 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)。

有什么建议吗?

java ipv6
5个回答
6
投票

java-ipv6 是一个非常不错的库。它还可以很好地处理地址范围。


2
投票
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)。这也将防止已经压缩的地址。


2
投票

开源IPAddress Java库可以进行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
投票

你可以试试这个代码。它可能会比正则表达式的等效项表现得更好(不是我对它进行了基准测试,或者其他什么)。它也经过了很好的测试。

请注意,您需要使用 IP 地址的数字表示形式(在

byte[]
中)。要获得它,如果您需要解析主机名,可以执行
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);
        }
    }
}

0
投票
import com.google.common.net.InetAddresses;
// Convert the short IPv6 address to a full version
InetAddress inetAddress = InetAddresses.forString(shortIPv6); 
return inetAddress.getHostAddress();
© www.soinside.com 2019 - 2024. All rights reserved.