用于将长IPv6地址转换为压缩forms的Java库

我想知道,是否有一个库可以用来将长IPv6地址的代表(例如2002:9876:57AB:0000:0000:0000:0000:0001)转换为压缩的IPv6格式(在这种情况:2002:9876:57AB :: 1)。

我找不到这样的图书馆。 此库不应使用任何IP Api,不得进行网络连接。

我已经试过了

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

但这只是将1个零替换为4个零(在本例中为2002:9876:57AB:0:0:0:0:1)。

有什么建议?

 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)。 这也可以防止已压缩的地址。

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

开源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 

您可以尝试此代码。 它可能比正则表达式更好(不是我对它进行了基准测试,或者其他任何东西)。 它也经过了很好的测试。

请注意,您需要使用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); } } }