我想知道,是否有一个库可用于将长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)。
有什么建议吗?
答案 0 :(得分:5)
java-ipv6是一个非常体面的图书馆。它还可以很好地处理地址范围。
答案 1 :(得分:3)
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 :(得分:1)
The open-source IPAddress Java library可以进行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
答案 3 :(得分: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);
}
}
}