This commit is contained in:
Looly 2023-04-15 10:51:19 +08:00
parent 8a2dfafea9
commit 241aea60e4
2 changed files with 80 additions and 47 deletions

View File

@ -63,9 +63,9 @@ public class Ipv4Util implements Ipv4Pool {
* @since 5.4.4 * @since 5.4.4
*/ */
public static String getLocalHostName() { public static String getLocalHostName() {
if(null == localhostName){ if (null == localhostName) {
synchronized (Ipv4Util.class){ synchronized (Ipv4Util.class) {
if(null == localhostName){ if (null == localhostName) {
localhostName = NetUtil.getAddressName(getLocalhostDirectly()); localhostName = NetUtil.getAddressName(getLocalhostDirectly());
} }
} }
@ -129,17 +129,19 @@ public class Ipv4Util implements Ipv4Pool {
* @return 本机网卡IP地址获取失败返回{@code null} * @return 本机网卡IP地址获取失败返回{@code null}
*/ */
public static InetAddress getLocalhostDirectly() { public static InetAddress getLocalhostDirectly() {
final LinkedHashSet<InetAddress> localAddressList = NetUtil.localAddressList(address -> { final LinkedHashSet<InetAddress> localAddressList = NetUtil.localAddressList(address ->
// 非loopback地址指127.*.*.*的地址 // 需为IPV4地址
return !address.isLoopbackAddress() address instanceof Inet4Address
// 非loopback地址指127.*.*.*的地址
&& !address.isLoopbackAddress()
// 非地区本地地址 // 非地区本地地址
// 10.0.0.0 ~ 10.255.255.255 // 10.0.0.0 ~ 10.255.255.255
// 172.16.0.0 ~ 172.31.255.255 // 172.16.0.0 ~ 172.31.255.255
// 192.168.0.0 ~ 192.168.255.255 // 192.168.0.0 ~ 192.168.255.255
&& !address.isSiteLocalAddress() && !address.isSiteLocalAddress()
// 需为IPV4地址 // 非链路本地地址169.254.0.0/16
&& address instanceof Inet4Address; && !address.isLinkLocalAddress()
}); );
if (CollUtil.isNotEmpty(localAddressList)) { if (CollUtil.isNotEmpty(localAddressList)) {
// 如果存在多网卡返回首个地址 // 如果存在多网卡返回首个地址
@ -148,7 +150,7 @@ public class Ipv4Util implements Ipv4Pool {
try { try {
final InetAddress localHost = InetAddress.getLocalHost(); final InetAddress localHost = InetAddress.getLocalHost();
if(localHost instanceof Inet4Address){ if (localHost instanceof Inet4Address) {
return localHost; return localHost;
} }
} catch (final UnknownHostException e) { } catch (final UnknownHostException e) {
@ -274,10 +276,10 @@ public class Ipv4Util implements Ipv4Pool {
for (long ip = ipFrom, end = ipTo + 1; ip < end; ip++) { for (long ip = ipFrom, end = ipTo + 1; ip < end; ip++) {
sb.setLength(0); sb.setLength(0);
ips.add(sb.append((int) (ip >> 24) & 0xFF).append(CharUtil.DOT) ips.add(sb.append((int) (ip >> 24) & 0xFF).append(CharUtil.DOT)
.append((int) (ip >> 16) & 0xFF).append(CharUtil.DOT) .append((int) (ip >> 16) & 0xFF).append(CharUtil.DOT)
.append((int) (ip >> 8) & 0xFF).append(CharUtil.DOT) .append((int) (ip >> 8) & 0xFF).append(CharUtil.DOT)
.append((int) ip & 0xFF) .append((int) ip & 0xFF)
.toString()); .toString());
} }
return ips; return ips;
} }
@ -290,11 +292,11 @@ public class Ipv4Util implements Ipv4Pool {
*/ */
public static String longToIpv4(final long ip) { public static String longToIpv4(final long ip) {
return StrUtil.builder(15) return StrUtil.builder(15)
.append((int) (ip >> 24) & 0xFF).append(CharUtil.DOT) .append((int) (ip >> 24) & 0xFF).append(CharUtil.DOT)
.append((int) (ip >> 16) & 0xFF).append(CharUtil.DOT) .append((int) (ip >> 16) & 0xFF).append(CharUtil.DOT)
.append((int) (ip >> 8) & 0xFF).append(CharUtil.DOT) .append((int) (ip >> 8) & 0xFF).append(CharUtil.DOT)
.append((int) ip & 0xFF) .append((int) ip & 0xFF)
.toString(); .toString();
} }
/** /**
@ -378,7 +380,7 @@ public class Ipv4Util implements Ipv4Pool {
*/ */
public static int countByMaskBit(final int maskBit, final boolean isAll) { public static int countByMaskBit(final int maskBit, final boolean isAll) {
Assert.isTrue(maskBit > IPV4_MASK_BIT_VALID_MIN && maskBit <= IPV4_MASK_BIT_MAX, Assert.isTrue(maskBit > IPV4_MASK_BIT_VALID_MIN && maskBit <= IPV4_MASK_BIT_MAX,
"Not support mask bit: {}", maskBit); "Not support mask bit: {}", maskBit);
//如果掩码位等于32则可用地址为0 //如果掩码位等于32则可用地址为0
if (maskBit == IPV4_MASK_BIT_MAX && !isAll) { if (maskBit == IPV4_MASK_BIT_MAX && !isAll) {
return 0; return 0;
@ -412,11 +414,11 @@ public class Ipv4Util implements Ipv4Pool {
Assert.isTrue(fromIpLong <= toIpLong, "Start IP must be less than or equal to end IP!"); Assert.isTrue(fromIpLong <= toIpLong, "Start IP must be less than or equal to end IP!");
return StrUtil.builder(15) return StrUtil.builder(15)
.append(255 - getPartOfIp(toIpLong, 1) + getPartOfIp(fromIpLong, 1)).append(CharUtil.DOT) .append(255 - getPartOfIp(toIpLong, 1) + getPartOfIp(fromIpLong, 1)).append(CharUtil.DOT)
.append(255 - getPartOfIp(toIpLong, 2) + getPartOfIp(fromIpLong, 2)).append(CharUtil.DOT) .append(255 - getPartOfIp(toIpLong, 2) + getPartOfIp(fromIpLong, 2)).append(CharUtil.DOT)
.append(255 - getPartOfIp(toIpLong, 3) + getPartOfIp(fromIpLong, 3)).append(CharUtil.DOT) .append(255 - getPartOfIp(toIpLong, 3) + getPartOfIp(fromIpLong, 3)).append(CharUtil.DOT)
.append(255 - getPartOfIp(toIpLong, 4) + getPartOfIp(fromIpLong, 4)) .append(255 - getPartOfIp(toIpLong, 4) + getPartOfIp(fromIpLong, 4))
.toString(); .toString();
} }
/** /**
@ -442,9 +444,9 @@ public class Ipv4Util implements Ipv4Pool {
int count = 1; int count = 1;
count += (getPartOfIp(toIp, 4) - getPartOfIp(fromIp, 4)) count += (getPartOfIp(toIp, 4) - getPartOfIp(fromIp, 4))
+ ((getPartOfIp(toIp, 3) - getPartOfIp(fromIp, 3)) << 8) + ((getPartOfIp(toIp, 3) - getPartOfIp(fromIp, 3)) << 8)
+ ((getPartOfIp(toIp, 2) - getPartOfIp(fromIp, 2)) << 16) + ((getPartOfIp(toIp, 2) - getPartOfIp(fromIp, 2)) << 16)
+ ((getPartOfIp(toIp, 1) - getPartOfIp(fromIp, 1)) << 24); + ((getPartOfIp(toIp, 1) - getPartOfIp(fromIp, 1)) << 24);
return count; return count;
} }
@ -496,9 +498,9 @@ public class Ipv4Util implements Ipv4Pool {
*/ */
public static boolean isInnerIP(final long ipNum) { public static boolean isInnerIP(final long ipNum) {
return isBetween(ipNum, IPV4_A_PRIVATE_NUM_MIN, IPV4_A_PRIVATE_NUM_MAX) return isBetween(ipNum, IPV4_A_PRIVATE_NUM_MIN, IPV4_A_PRIVATE_NUM_MAX)
|| isBetween(ipNum, IPV4_B_PRIVATE_NUM_MIN, IPV4_B_PRIVATE_NUM_MAX) || isBetween(ipNum, IPV4_B_PRIVATE_NUM_MIN, IPV4_B_PRIVATE_NUM_MAX)
|| isBetween(ipNum, IPV4_C_PRIVATE_NUM_MIN, IPV4_C_PRIVATE_NUM_MAX) || isBetween(ipNum, IPV4_C_PRIVATE_NUM_MIN, IPV4_C_PRIVATE_NUM_MAX)
|| LOCAL_IP_NUM == ipNum; || LOCAL_IP_NUM == ipNum;
} }
/** /**
@ -529,11 +531,11 @@ public class Ipv4Util implements Ipv4Pool {
*/ */
public static boolean isPublicIP(final long ipNum) { public static boolean isPublicIP(final long ipNum) {
return isBetween(ipNum, IPV4_A_PUBLIC_1_NUM_MIN, IPV4_A_PUBLIC_1_NUM_MAX) return isBetween(ipNum, IPV4_A_PUBLIC_1_NUM_MIN, IPV4_A_PUBLIC_1_NUM_MAX)
|| isBetween(ipNum, IPV4_A_PUBLIC_2_NUM_MIN, IPV4_A_PUBLIC_2_NUM_MAX) || isBetween(ipNum, IPV4_A_PUBLIC_2_NUM_MIN, IPV4_A_PUBLIC_2_NUM_MAX)
|| isBetween(ipNum, IPV4_B_PUBLIC_1_NUM_MIN, IPV4_B_PUBLIC_1_NUM_MAX) || isBetween(ipNum, IPV4_B_PUBLIC_1_NUM_MIN, IPV4_B_PUBLIC_1_NUM_MAX)
|| isBetween(ipNum, IPV4_B_PUBLIC_2_NUM_MIN, IPV4_B_PUBLIC_2_NUM_MAX) || isBetween(ipNum, IPV4_B_PUBLIC_2_NUM_MIN, IPV4_B_PUBLIC_2_NUM_MAX)
|| isBetween(ipNum, IPV4_C_PUBLIC_1_NUM_MIN, IPV4_C_PUBLIC_1_NUM_MAX) || isBetween(ipNum, IPV4_C_PUBLIC_1_NUM_MIN, IPV4_C_PUBLIC_1_NUM_MAX)
|| isBetween(ipNum, IPV4_C_PUBLIC_2_NUM_MIN, IPV4_C_PUBLIC_2_NUM_MAX); || isBetween(ipNum, IPV4_C_PUBLIC_2_NUM_MIN, IPV4_C_PUBLIC_2_NUM_MAX);
} }
/** /**
@ -560,7 +562,7 @@ public class Ipv4Util implements Ipv4Pool {
case 3: case 3:
return (int) (ip >> 8) & 0xFF; return (int) (ip >> 8) & 0xFF;
case 4: case 4:
return (int)ip & 0xFF; return (int) ip & 0xFF;
default: default:
throw new IllegalArgumentException("Illegal position of ip Long: " + position); throw new IllegalArgumentException("Illegal position of ip Long: " + position);
} }

View File

@ -13,6 +13,7 @@
package org.dromara.hutool.core.net; package org.dromara.hutool.core.net;
import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.exceptions.UtilException;
import org.dromara.hutool.core.lang.Singleton; import org.dromara.hutool.core.lang.Singleton;
import java.math.BigInteger; import java.math.BigInteger;
@ -85,9 +86,9 @@ public class Ipv6Util {
* @since 5.4.4 * @since 5.4.4
*/ */
public static String getLocalHostName() { public static String getLocalHostName() {
if(null == localhostName){ if (null == localhostName) {
synchronized (Ipv4Util.class){ synchronized (Ipv4Util.class) {
if(null == localhostName){ if (null == localhostName) {
localhostName = NetUtil.getAddressName(getLocalhostDirectly()); localhostName = NetUtil.getAddressName(getLocalhostDirectly());
} }
} }
@ -148,14 +149,16 @@ public class Ipv6Util {
* @return 本机网卡IP地址获取失败返回{@code null} * @return 本机网卡IP地址获取失败返回{@code null}
*/ */
public static InetAddress getLocalhostDirectly() { public static InetAddress getLocalhostDirectly() {
final LinkedHashSet<InetAddress> localAddressList = NetUtil.localAddressList(address -> { final LinkedHashSet<InetAddress> localAddressList = NetUtil.localAddressList(address ->
// 非loopback地址 // 需为IPV6地址
return !address.isLoopbackAddress() address instanceof Inet6Address
// 非地区本地地址 // 非loopback地址::1
&& !address.isLoopbackAddress()
// 非地区本地地址fec0::/10
&& !address.isSiteLocalAddress() && !address.isSiteLocalAddress()
// 需为IPV6地址 // 非链路本地地址fe80::/10
&& address instanceof Inet6Address; && !address.isLinkLocalAddress()
}); );
if (CollUtil.isNotEmpty(localAddressList)) { if (CollUtil.isNotEmpty(localAddressList)) {
// 如果存在多网卡返回首个地址 // 如果存在多网卡返回首个地址
@ -173,4 +176,32 @@ public class Ipv6Util {
return null; return null;
} }
/**
* 规范IPv6地址转换scope名称为scope id
* <pre>
* fe80:0:0:0:894:aeec:f37d:23e1%en0
* |
* fe80:0:0:0:894:aeec:f37d:23e1%5
* </pre>
* <p>
* 地址后的%5 叫做 scope id.
* <p>
* 方法来自于Dubbo
*
* @param address IPv6地址
* @return 规范之后的IPv6地址使用scope id
*/
public static InetAddress normalizeV6Address(final Inet6Address address) {
final String addr = address.getHostAddress();
final int index = addr.lastIndexOf('%');
if (index > 0) {
try {
return InetAddress.getByName(addr.substring(0, index) + '%' + address.getScopeId());
} catch (final UnknownHostException e) {
throw new UtilException(e);
}
}
return address;
}
} }