All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nervousync.utils.IPUtils Maven / Gradle / Ivy

There is a newer version: 1.2.1
Show newest version
/*
 * Licensed to the Nervousync Studio (NSYC) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.
 */
package org.nervousync.utils;

import jakarta.annotation.Nonnull;
import org.nervousync.beans.ip.IPRange;
import org.nervousync.commons.Globals;
import org.nervousync.commons.RegexGlobals;
import org.nervousync.enumerations.ip.IPType;

import java.math.BigInteger;

/**
 * 

IP Address Utilities

* * Current utilities implements features: *
    Calculate IP range by given address and CIDR value
*
    Convert between netmask address and CIDR value
*
    Convert between IPv4 and IPv6
*
    Convert between IP address and BigInteger(for support IPv6)
*
    Expand the combo IPv6 address
*
*

IP地址工具

* * 此工具集实现以下功能: *
    根据给定的地址和CIDR,计算IP地址范围
*
    在子网掩码和CIDR之间转换数据
*
    在IPv4和IPv6之间转换数据
*
    在IP地址和BigInteger之间转换数据
*
    将压缩显示的IPv6地址展开
*
* * @author Steven Wee [email protected] * @version $Revision: 1.2.0 $ $Date: Aug 15, 2022 16:23:13 $ */ public final class IPUtils { /** * Split character for IPv4 address * IPv4地址的间隔符 */ private static final String SPLIT_CHARACTER_IPV4 = "."; /** * Split character for IPv6 address * IPv6地址的间隔符 */ private static final String SPLIT_CHARACTER_IPV6 = ":"; /** * Split character for combo IPv6 address * IPv6压缩地址的间隔符 */ private static final String SPLIT_COMBO_CHARACTER_IPV6 = "::"; /** *

Private constructor for IPUtils

*

IP地址工具集的私有构造方法

*/ private IPUtils() { } /** *

Calculate IP range by given address and CIDR value

*

根据给定的地址和CIDR,计算IP地址范围

* * @param ipAddress IP address * IP地址 * @param cidr CIDR value * CIDR值 * * @return Calculate result of IPRange instance * 根据计算结果生成的IPRange对象 */ public static IPRange calcRange(@Nonnull final String ipAddress, final int cidr) { IPRange ipRange = new IPRange(); final String beginAddress; final String endAddress; if (ipAddress.contains(SPLIT_CHARACTER_IPV6)) { ipRange.setIpType(IPType.IPv6); beginAddress = beginIPv6(ipAddress, cidr); endAddress = endIPv6(beginAddress, cidr); } else { ipRange.setIpType(IPType.IPv4); String netmask = CIDRToNetmask(cidr); beginAddress = beginIPv4(ipAddress, netmask); endAddress = endIPv4(beginAddress, netmask); } ipRange.setBeginAddress(beginAddress); ipRange.setEndAddress(endAddress); return ipRange; } /** *

Convert netmask string to CIDR value

*

转换子网掩码字符串为CIDR值

* * @param netmask IP address * IP地址 * * @return CIDR value * CIDR值 */ public static int NetmaskToCIDR(@Nonnull final String netmask) { int result = 0; String[] splitItems = StringUtils.tokenizeToStringArray(netmask, SPLIT_CHARACTER_IPV4); for (String splitItem : splitItems) { int number = Integer.parseInt(splitItem); while (number > 0) { if ((number % 2) == 1) { result++; } number /= 2; } } return result; } /** *

Convert CIDR value to netmask string

*

转换CIDR值为子网掩码字符串

* * @param cidr CIDR value * CIDR值 * * @return Netmask address string * 子网掩码字符串 */ public static String CIDRToNetmask(final int cidr) { int calcCIDR = cidr; if (calcCIDR >= 0 && calcCIDR <= 32) { StringBuilder stringBuilder = new StringBuilder(); int index = 0; while (index < 4) { stringBuilder.append(SPLIT_CHARACTER_IPV4).append(fillBitsFromLeft(calcCIDR)); calcCIDR -= 8; if (calcCIDR < 0) { calcCIDR = 0; } index++; } return stringBuilder.substring(1); } return Globals.DEFAULT_VALUE_STRING; } /** *

Check given IP address string is IPv4 address

*

检查给定的IP地址字符串是合法的IPv4地址

* * @param ipAddress IP address string * IP地址字符串 * * @return Check result. true for valid, false for invalid * 检查结果。true合法地址,false非法地址 */ public static boolean isIPv4Address(@Nonnull final String ipAddress) { return StringUtils.matches(ipAddress, RegexGlobals.IPV4_REGEX); } /** *

Check given IP address string is IPv6 address

*

检查给定的IP地址字符串是合法的IPv6地址

* * @param ipAddress IP address string * IP地址字符串 * * @return Check result. true for valid, false for invalid * 检查结果。true合法地址,false非法地址 */ public static boolean isIPv6Address(@Nonnull final String ipAddress) { return StringUtils.matches(ipAddress, RegexGlobals.IPV6_REGEX) || StringUtils.matches(ipAddress, RegexGlobals.IPV6_COMPRESS_REGEX); } /** *

Convert given IPv4 address string to compatible IPv6 address

*

转换给定的IPv4地址为IPv6兼容地址

* * @param ipAddress IPv4 address string * IP地址字符串 * * @return Compatible IPv6 address string * 转换后的IPv6兼容地址 */ public static String IPv4ToCompatibleIPv6(@Nonnull final String ipAddress) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV4_REGEX)) { return SPLIT_COMBO_CHARACTER_IPV6 + ipAddress; } return null; } /** *

Convert given IPv4 address string to IPv6 address

*

转换给定的IPv4地址为IPv6兼容地址

* * @param ipAddress IPv4 address string * IP地址字符串 * * @return IPv6 address string * 转换后的IPv6地址 */ public static String IPv4ToIPv6(@Nonnull final String ipAddress) { return IPv4ToIPv6(ipAddress, Boolean.TRUE); } /** *

Convert given IPv4 address string to IPv6 address

*

转换给定的IPv4地址为IPv6兼容地址

* * @param ipAddress IPv4 address string * IP地址字符串 * @param collapse Collapse converted IPv6 address * 是否简写IPv6地址 * * @return IPv6 address string * 转换后的IPv6地址 */ public static String IPv4ToIPv6(@Nonnull final String ipAddress, final boolean collapse) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV4_REGEX)) { String[] splitAddress = StringUtils.tokenizeToStringArray(ipAddress, SPLIT_CHARACTER_IPV4); StringBuilder stringBuilder; if (collapse) { stringBuilder = new StringBuilder(SPLIT_CHARACTER_IPV6); } else { stringBuilder = new StringBuilder("0000:0000:0000:0000:0000:0000"); } int index = 0; for (String addressItem : splitAddress) { if (index % 2 == 0) { stringBuilder.append(SPLIT_CHARACTER_IPV6); } stringBuilder.append(Integer.toHexString(Integer.parseInt(addressItem))); index++; } return stringBuilder.toString().toUpperCase(); } return null; } /** *

Convert given IP address string to byte array

*

转换给定的IP地址为字节数组

* * @param ipAddress IP address string * IP地址字符串 * * @return Converted byte array * 转换后的字节数组 */ public static byte[] IPToBytes(@Nonnull final String ipAddress) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV4_REGEX)) { return IPv4ToBytes(ipAddress); } else if (StringUtils.matches(ipAddress, RegexGlobals.IPV6_REGEX) || StringUtils.matches(ipAddress, RegexGlobals.IPV6_COMPRESS_REGEX)) { return IPv6ToBytes(ipAddress); } else { return new byte[0]; } } /** *

Convert given IPv4 address string to byte array

*

转换给定的IPv4地址为字节数组

* * @param ipAddress IPv4 address string * IPv4地址字符串 * * @return Converted byte array * 转换后的字节数组 */ public static byte[] IPv4ToBytes(@Nonnull final String ipAddress) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV4_REGEX)) { String[] splitAddress = StringUtils.tokenizeToStringArray(ipAddress, SPLIT_CHARACTER_IPV4); byte[] addressBytes = new byte[4]; addressBytes[0] = (byte) Integer.parseInt(splitAddress[0]); addressBytes[1] = (byte) Integer.parseInt(splitAddress[1]); addressBytes[2] = (byte) Integer.parseInt(splitAddress[2]); addressBytes[3] = (byte) Integer.parseInt(splitAddress[3]); return addressBytes; } return null; } /** *

Convert given IPv6 address string to byte array

*

转换给定的IPv6地址为字节数组

* * @param ipAddress IPv6 address string * IPv6地址字符串 * * @return Converted byte array * 转换后的字节数组 */ public static byte[] IPv6ToBytes(@Nonnull final String ipAddress) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV6_REGEX) || StringUtils.matches(ipAddress, RegexGlobals.IPV6_COMPRESS_REGEX)) { String ipv6Address = expandIPv6(ipAddress); String[] splitAddress = StringUtils.tokenizeToStringArray(ipv6Address, SPLIT_CHARACTER_IPV6); byte[] addressBytes = new byte[16]; int index = 0; for (String address : splitAddress) { int tmp = Integer.parseInt(address, 16); addressBytes[index] = (byte) (tmp >> 8); addressBytes[index + 1] = (byte) tmp; index += 2; } return addressBytes; } return null; } /** *

Expand the given combo IPv6 address string

*

展开给定的缩略IPv6地址字符串

* * @param ipAddress Combo IPv6 address string * 缩略的IPv6地址字符串 * * @return Expanded IPv6 address string * 展开后的IPv6地址字符串 */ public static String expandIPv6(@Nonnull final String ipAddress) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV6_COMPRESS_REGEX)) { int sigCount = StringUtils.countOccurrencesOf(ipAddress, SPLIT_CHARACTER_IPV6); int expandCount = 8 - sigCount; int position = 0; StringBuilder stringBuilder = new StringBuilder(); while (true) { int index = ipAddress.indexOf(SPLIT_CHARACTER_IPV6, position); if (index == Globals.DEFAULT_VALUE_INT) { stringBuilder.append(SPLIT_CHARACTER_IPV6).append(ipAddress.substring(position)); break; } else { if (index == position) { while (expandCount > 0) { stringBuilder.append(":0"); expandCount--; } } else { stringBuilder.append(SPLIT_CHARACTER_IPV6).append(ipAddress, position, index); } position = index + 1; } } return stringBuilder.substring(1); } return ipAddress; } /** *

Convert given IP address string to BigInteger instance

*

转换给定的IP地址为BigInteger实例对象

* * @param ipAddress IP address string * IP地址字符串 * * @return Converted BigInteger instance * 转换后的BigInteger实例对象 */ public static BigInteger IPtoBigInteger(@Nonnull final String ipAddress) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV4_REGEX)) { return IPv4ToBigInteger(ipAddress); } else { return IPv6ToBigInteger(ipAddress); } } /** *

Convert given IPv4 address string to BigInteger instance

*

转换给定的IPv4地址为BigInteger实例对象

* * @param ipAddress IPv4 address string * IPv4地址字符串 * * @return Converted BigInteger instance * 转换后的BigInteger实例对象 */ public static BigInteger IPv4ToBigInteger(@Nonnull final String ipAddress) { if (StringUtils.matches(ipAddress, RegexGlobals.IPV4_REGEX)) { String[] splitAddress = StringUtils.tokenizeToStringArray(ipAddress, SPLIT_CHARACTER_IPV4); if (splitAddress.length == 4) { long result = 0L; for (int i = 0; i < splitAddress.length; i++) { result += (Long.parseLong(splitAddress[i]) << 8 * (3 - i)); } return BigInteger.valueOf(result); } } return BigInteger.ZERO; } /** *

Convert given IPv6address string to BigInteger instance

*

转换给定的IPv6地址为BigInteger实例对象

* * @param ipAddress IPv6 address string * IPv6地址字符串 * * @return Converted BigInteger instance * 转换后的BigInteger实例对象 */ public static BigInteger IPv6ToBigInteger(@Nonnull final String ipAddress) { String fullAddress = expandIgnore(ipAddress); if (StringUtils.matches(fullAddress, RegexGlobals.IPV6_REGEX)) { String[] splitAddress = StringUtils.tokenizeToStringArray(fullAddress, SPLIT_CHARACTER_IPV6); BigInteger bigInteger = BigInteger.ZERO; int index = 0; for (String split : splitAddress) { BigInteger currentInteger; if (StringUtils.matches(split, RegexGlobals.IPV4_REGEX)) { currentInteger = IPv4ToBigInteger(split); } else { currentInteger = BigInteger.valueOf(Long.valueOf(split, 16)); } if (currentInteger == null) { return BigInteger.ZERO; } bigInteger = bigInteger.add(currentInteger.shiftLeft(16 * (splitAddress.length - index - 1))); index++; } return bigInteger; } return BigInteger.ZERO; } /** *

Convert given BigInteger instance to IPv4 address string

*

转换给定的BigInteger实例对象为IPv4地址字符串

* * @param bigInteger BigInteger instance * BigInteger实例对象 * * @return Converted IPv4 address string * 转换后的IPv4地址字符串 */ public static String BigIntegerToIPv4(@Nonnull final BigInteger bigInteger) { StringBuilder ipv4Address = new StringBuilder(); BigInteger calcInteger = new BigInteger(bigInteger.toByteArray()); BigInteger ff = BigInteger.valueOf(0xFFL); for (int i = 0; i < 4; i++) { ipv4Address.insert(0, SPLIT_CHARACTER_IPV4 + calcInteger.and(ff)); calcInteger = calcInteger.shiftRight(8); } return ipv4Address.substring(1); } /** *

Convert given BigInteger instance to IPv6 address string

*

转换给定的BigInteger实例对象为IPv6地址字符串

* * @param bigInteger BigInteger instance * BigInteger实例对象 * * @return Converted IPv6 address string * 转换后的IPv6地址字符串 */ public static String BigIntegerToIPv6Address(@Nonnull final BigInteger bigInteger) { StringBuilder ipv6Address = new StringBuilder(); BigInteger calcInteger = new BigInteger(bigInteger.toByteArray()); BigInteger ff = BigInteger.valueOf(0xFFFFL); for (int i = 0; i < 8; i++) { ipv6Address.insert(0, SPLIT_CHARACTER_IPV6 + calcInteger.and(ff).toString(16)); calcInteger = calcInteger.shiftRight(16); } return ipv6Address.substring(1).replaceFirst(RegexGlobals.IPV6_COMPRESS_REGEX, SPLIT_COMBO_CHARACTER_IPV6); } /** *

Expand the given combo IPv6 address string and append 0

*

展开给定的缩略IPv6地址字符串并填充0

* * @param ipv6Address Combo IPv6 address string * 缩略的IPv6地址字符串 * * @return Expanded IPv6 address string * 展开后的IPv6地址字符串 */ public static String expandIgnore(@Nonnull final String ipv6Address) { String resultAddress = ipv6Address; if (resultAddress.contains("::")) { int count = StringUtils.countOccurrencesOf(resultAddress, SPLIT_CHARACTER_IPV6); resultAddress = StringUtils.replace(resultAddress, SPLIT_COMBO_CHARACTER_IPV6, ":0000".repeat(Math.max(0, 8 - count)) + SPLIT_CHARACTER_IPV6); if (resultAddress.startsWith(SPLIT_CHARACTER_IPV6)) { resultAddress = "0000" + resultAddress; } if (resultAddress.endsWith(SPLIT_CHARACTER_IPV6)) { resultAddress += "0000"; } } String[] addressItems = StringUtils.delimitedListToStringArray(resultAddress, SPLIT_CHARACTER_IPV6); StringBuilder stringBuilder = new StringBuilder(); for (String addressItem : addressItems) { StringBuilder addressItemBuilder = new StringBuilder(addressItem); while (addressItemBuilder.length() < 4) { addressItemBuilder.insert(0, "0"); } addressItem = addressItemBuilder.toString(); stringBuilder.append(SPLIT_CHARACTER_IPV6).append(addressItem); } return stringBuilder.substring(1); } /** *

Calculate the begin IP address by given IP address and netmask string

*

根据给定的IP地址和子网掩码字符串计算起始IP地址

* * @param ipAddress IP address string * IP地址字符串 * @param netmask IP address * IP地址 * * @return Begin IPv4 address string * 起始的IPv4地址字符串 */ private static String beginIPv4(@Nonnull final String ipAddress, @Nonnull final String netmask) { String[] addressItems = StringUtils.tokenizeToStringArray(ipAddress, SPLIT_CHARACTER_IPV4); String[] maskItems = StringUtils.tokenizeToStringArray(netmask, SPLIT_CHARACTER_IPV4); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < 4; i++) { int itemValue = i < addressItems.length ? Integer.parseInt(addressItems[i]) : Globals.INITIALIZE_INT_VALUE; int beginItem = itemValue & Integer.parseInt(maskItems[i]); if (itemValue == 0 && i == 3) { beginItem++; } stringBuilder.append(SPLIT_CHARACTER_IPV4).append(beginItem); } return stringBuilder.substring(1); } /** *

Calculate the end IP address by given IP address and netmask string

*

根据给定的IP地址和子网掩码字符串计算起始IP地址

* * @param beginIP Begin IP address string * 起始IP地址字符串 * @param netmask IP address * IP地址 * * @return End IPv4 address string * 终止的IPv4地址字符串 */ private static String endIPv4(@Nonnull final String beginIP, @Nonnull final String netmask) { String[] addressItems = StringUtils.tokenizeToStringArray(beginIP, SPLIT_CHARACTER_IPV4); String[] maskItems = StringUtils.tokenizeToStringArray(netmask, SPLIT_CHARACTER_IPV4); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < 4; i++) { int endItem = 255 - Integer.parseInt(addressItems[i]) ^ Integer.parseInt(maskItems[i]); stringBuilder.append(SPLIT_CHARACTER_IPV4).append(endItem); } return stringBuilder.substring(1); } /** *

Calculate the begin IPv6 address by given IP address and netmask string

*

根据给定的IP地址和子网掩码字符串计算起始IP地址

* * @param ipAddress IP address string * IP地址字符串 * @param cidr CIDR value * CIDR值 * * @return Begin IPv6 address string * 起始的IPv6地址字符串 */ private static String beginIPv6(@Nonnull final String ipAddress, final int cidr) { if (cidr >= Globals.INITIALIZE_INT_VALUE && cidr <= 128) { String hexAddress = StringUtils.replace(expandIgnore(ipAddress), SPLIT_CHARACTER_IPV6, Globals.DEFAULT_VALUE_STRING); StringBuilder baseIP = new StringBuilder(hexToBin(hexAddress).substring(Globals.INITIALIZE_INT_VALUE, cidr)); while (baseIP.length() < 128) { baseIP.append("0"); } return binToHex(baseIP.toString()); } return Globals.DEFAULT_VALUE_STRING; } /** *

Calculate the end IPv6 address by given begin IPv6 address and netmask string

*

根据给定的IP地址和子网掩码字符串计算起始IP地址

* * @param beginIP Begin IPv6 address string * 起始IPv6地址字符串 * @param cidr CIDR value * CIDR值 * * @return End IPv6 address string * 终止的IPv6地址字符串 */ private static String endIPv6(@Nonnull final String beginIP, final int cidr) { if (cidr >= Globals.INITIALIZE_INT_VALUE && cidr <= 128) { String hexAddress = StringUtils.replace(expandIgnore(beginIP), SPLIT_CHARACTER_IPV6, Globals.DEFAULT_VALUE_STRING); StringBuilder baseIP = new StringBuilder(hexToBin(hexAddress).substring(Globals.INITIALIZE_INT_VALUE, cidr)); while (baseIP.length() < 128) { baseIP.append("1"); } return binToHex(baseIP.toString()); } return Globals.DEFAULT_VALUE_STRING; } /** *

Convert hex address to binary string

*

转换16进制地址为二进制地址字符串

* * @param hexAddress Hex address string * 16进制地址字符串 * * @return Binary address string * 二进制地址字符串 */ private static String hexToBin(@Nonnull final String hexAddress) { StringBuilder binBuilder = new StringBuilder(); int index = 0; while (index < hexAddress.length()) { int hexInt = Integer.parseInt(hexAddress.substring(index, index + 1), 16); StringBuilder binItem = new StringBuilder(Integer.toString(hexInt, 2)); while (binItem.length() < 4) { binItem.insert(0, "0"); } binBuilder.append(binItem); index++; } return binBuilder.toString(); } /** *

Convert binary address to hex string

*

转换16进制地址为二进制地址字符串

* * @param binAddress Binary address string * 二进制地址字符串 * * @return Hex address string * 16进制地址字符串 */ private static String binToHex(@Nonnull final String binAddress) { StringBuilder binBuilder = new StringBuilder(); int index = 0; while (index < binAddress.length()) { if (index % 16 == 0) { binBuilder.append(SPLIT_CHARACTER_IPV6); } int binInt = Integer.parseInt(binAddress.substring(index, index + 4), 2); binBuilder.append(Integer.toString(binInt, 16).toUpperCase()); index += 4; } return binBuilder.substring(1); } private static int fillBitsFromLeft(final int value) { if (value >= 8) { return 255; } else { return 256 - Double.valueOf(Math.pow(2, (8 - value))).intValue(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy