Here you can find the source of toAddressString(InetAddress ip)
Parameter | Description |
---|---|
ip | InetAddress to be converted to an address string |
public static String toAddressString(InetAddress ip)
//package com.java2s; /*/*from w w w .j ava 2 s. co m*/ * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; public class Main { /** * This defines how many words (represented as ints) are needed to represent an IPv6 address */ private static final int IPV6_WORD_COUNT = 8; /** * The maximum number of characters for an IPV6 string with no scope */ private static final int IPV6_MAX_CHAR_COUNT = 39; /** * Returns the {@link String} representation of an {@link InetAddress}. * <ul> * <li>Inet4Address results are identical to {@link InetAddress#getHostAddress()}</li> * <li>Inet6Address results adhere to * <a href="http://tools.ietf.org/html/rfc5952#section-4">rfc 5952 section 4</a></li> * </ul> * <p> * The output does not include Scope ID. * @param ip {@link InetAddress} to be converted to an address string * @return {@code String} containing the text-formatted IP address */ public static String toAddressString(InetAddress ip) { return toAddressString(ip, false); } /** * Returns the {@link String} representation of an {@link InetAddress}. * <ul> * <li>Inet4Address results are identical to {@link InetAddress#getHostAddress()}</li> * <li>Inet6Address results adhere to * <a href="http://tools.ietf.org/html/rfc5952#section-4">rfc 5952 section 4</a> if * {@code ipv4Mapped} is false. If {@code ipv4Mapped} is true then "IPv4 mapped" format * from <a href="http://tools.ietf.org/html/rfc4291#section-2.5.5">rfc 4291 section 2</a> will be supported. * The compressed result will always obey the compression rules defined in * <a href="http://tools.ietf.org/html/rfc5952#section-4">rfc 5952 section 4</a></li> * </ul> * <p> * The output does not include Scope ID. * @param ip {@link InetAddress} to be converted to an address string * @param ipv4Mapped * <ul> * <li>{@code true} to stray from strict rfc 5952 and support the "IPv4 mapped" format * defined in <a href="http://tools.ietf.org/html/rfc4291#section-2.5.5">rfc 4291 section 2</a> while still * following the updated guidelines in * <a href="http://tools.ietf.org/html/rfc5952#section-4">rfc 5952 section 4</a></li> * <li>{@code false} to strictly follow rfc 5952</li> * </ul> * @return {@code String} containing the text-formatted IP address */ public static String toAddressString(InetAddress ip, boolean ipv4Mapped) { if (ip instanceof Inet4Address) { return ip.getHostAddress(); } if (!(ip instanceof Inet6Address)) { throw new IllegalArgumentException("Unhandled type: " + ip.getClass()); } final byte[] bytes = ip.getAddress(); final int[] words = new int[IPV6_WORD_COUNT]; int i; for (i = 0; i < words.length; ++i) { words[i] = ((bytes[i << 1] & 0xff) << 8) | (bytes[(i << 1) + 1] & 0xff); } // Find longest run of 0s, tie goes to first found instance int currentStart = -1; int currentLength = 0; int shortestStart = -1; int shortestLength = 0; for (i = 0; i < words.length; ++i) { if (words[i] == 0) { if (currentStart < 0) { currentStart = i; } } else if (currentStart >= 0) { currentLength = i - currentStart; if (currentLength > shortestLength) { shortestStart = currentStart; shortestLength = currentLength; } currentStart = -1; } } // If the array ends on a streak of zeros, make sure we account for it if (currentStart >= 0) { currentLength = i - currentStart; if (currentLength > shortestLength) { shortestStart = currentStart; shortestLength = currentLength; } } // Ignore the longest streak if it is only 1 long if (shortestLength == 1) { shortestLength = 0; shortestStart = -1; } // Translate to string taking into account longest consecutive 0s final int shortestEnd = shortestStart + shortestLength; final StringBuilder b = new StringBuilder(IPV6_MAX_CHAR_COUNT); if (shortestEnd < 0) { // Optimization when there is no compressing needed b.append(Integer.toHexString(words[0])); for (i = 1; i < words.length; ++i) { b.append(':'); b.append(Integer.toHexString(words[i])); } } else { // General case that can handle compressing (and not compressing) // Loop unroll the first index (so we don't constantly check i==0 cases in loop) final boolean isIpv4Mapped; if (inRangeEndExclusive(0, shortestStart, shortestEnd)) { b.append("::"); isIpv4Mapped = ipv4Mapped && (shortestEnd == 5 && words[5] == 0xffff); } else { b.append(Integer.toHexString(words[0])); isIpv4Mapped = false; } for (i = 1; i < words.length; ++i) { if (!inRangeEndExclusive(i, shortestStart, shortestEnd)) { if (!inRangeEndExclusive(i - 1, shortestStart, shortestEnd)) { // If the last index was not part of the shortened sequence if (!isIpv4Mapped || i == 6) { b.append(':'); } else { b.append('.'); } } if (isIpv4Mapped && i > 5) { b.append(words[i] >> 8); b.append('.'); b.append(words[i] & 0xff); } else { b.append(Integer.toHexString(words[i])); } } else if (!inRangeEndExclusive(i - 1, shortestStart, shortestEnd)) { // If we are in the shortened sequence and the last index was not b.append("::"); } } } return b.toString(); } /** * Does a range check on {@code value} if is within {@code start} (inclusive) and {@code end} (exclusive). * @param value The value to checked if is within {@code start} (inclusive) and {@code end} (exclusive) * @param start The start of the range (inclusive) * @param end The end of the range (exclusive) * @return * <ul> * <li>{@code true} if {@code value} if is within {@code start} (inclusive) and {@code end} (exclusive)</li> * <li>{@code false} otherwise</li> * </ul> */ private static boolean inRangeEndExclusive(int value, int start, int end) { return value >= start && value < end; } }