Вы можете попробовать этот код.Вероятно, он будет работать лучше, чем эквивалент регулярного выражения (не то, чтобы я его тестировал или что-то в этом роде).Он также довольно хорошо протестирован.
Обратите внимание, что вам нужно будет использовать числовое представление (в 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);
}
}
}