From 4bed6c554a223423b479a51739c4a4a9df39d002 Mon Sep 17 00:00:00 2001 From: emptypoint <1215582715@qq.com> Date: Sun, 12 Feb 2023 15:28:43 +0800 Subject: [PATCH] add method for ip Long; --- .../java/cn/hutool/core/net/Ipv4Util.java | 56 +++++++++++++------ .../main/java/cn/hutool/core/net/MaskBit.java | 12 ++++ 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/net/Ipv4Util.java b/hutool-core/src/main/java/cn/hutool/core/net/Ipv4Util.java index 23eebfff0..aad5addfc 100755 --- a/hutool-core/src/main/java/cn/hutool/core/net/Ipv4Util.java +++ b/hutool-core/src/main/java/cn/hutool/core/net/Ipv4Util.java @@ -137,7 +137,7 @@ public class Ipv4Util { } if (maskBit == IP_MASK_MAX) { - final List list = new ArrayList<>(); + final List list = new ArrayList<>(isAll ? 1 : 0); if (isAll) { list.add(ip); } @@ -168,10 +168,19 @@ public class Ipv4Util { * @return 区间内所有ip地址 */ public static List list(final String ipFrom, final String ipTo) { + return list(ipv4ToLong(ipFrom), ipv4ToLong(ipTo)); + } + + /** + * 得到指定区间内的所有IP地址 + * + * @param ipFrom 开始IP, 包含 + * @param ipTo 结束IP, 包含 + * @return 区间内所有ip地址,点分十进制表示 + */ + public static List list(final long ipFrom, final long ipTo) { // 确定ip数量 final int count = countByIpRange(ipFrom, ipTo); - final int[] from = Convert.convert(int[].class, StrUtil.splitToArray(ipFrom, CharUtil.DOT)); - final int[] to = Convert.convert(int[].class, StrUtil.splitToArray(ipTo, CharUtil.DOT)); final List ips = new ArrayList<>(count); // 是否是循环的第一个值 @@ -179,23 +188,23 @@ public class Ipv4Util { // 是否是循环的最后一个值 boolean aIsEnd, bIsEnd, cIsEnd; // 循环的结束值 - final int aEnd = to[0]; + final int aEnd = getPartOfIpLong(ipTo, 1); int bEnd; int cEnd; int dEnd; - for (int a = from[0]; a <= aEnd; a++) { + for (int a = getPartOfIpLong(ipFrom, 1); a <= aEnd; a++) { aIsEnd = (a == aEnd); // 本次循环的结束结束值 - bEnd = aIsEnd ? to[1] : 255; - for (int b = (aIsStart ? from[1] : 0); b <= bEnd; b++) { + bEnd = aIsEnd ? getPartOfIpLong(ipTo, 2) : 255; + for (int b = (aIsStart ? getPartOfIpLong(ipFrom, 2) : 0); b <= bEnd; b++) { // 在上一个循环是最后值的基础上进行判断 bIsEnd = aIsEnd && (b == bEnd); - cEnd = bIsEnd ? to[2] : 255; - for (int c = (bIsStart ? from[2] : 0); c <= cEnd; c++) { + cEnd = bIsEnd ? getPartOfIpLong(ipTo, 3) : 255; + for (int c = (bIsStart ? getPartOfIpLong(ipFrom, 3) : 0); c <= cEnd; c++) { // 在之前循环是最后值的基础上进行判断 cIsEnd = bIsEnd && (c == cEnd); - dEnd = cIsEnd ? to[3] : 255; - for (int d = (cIsStart ? from[3] : 0); d <= dEnd; d++) { + dEnd = cIsEnd ? getPartOfIpLong(ipTo, 4) : 255; + for (int d = (cIsStart ? getPartOfIpLong(ipFrom, 4) : 0); d <= dEnd; d++) { ips.add(a + "." + b + "." + c + "." + d); } cIsStart = false; @@ -256,7 +265,7 @@ public class Ipv4Util { */ public static Long getBeginIpLong(final String ip, final int maskBit) { assertMaskBitValid(maskBit); - return ipv4ToLong(ip) & ipv4ToLong(getMaskByMaskBit(maskBit)); + return ipv4ToLong(ip) & MaskBit.getMaskIpLong(maskBit); } /** @@ -278,7 +287,7 @@ public class Ipv4Util { * @return 终止IP的长整型表示 */ public static Long getEndIpLong(final String ip, final int maskBit) { - return getBeginIpLong(ip, maskBit) + ~ipv4ToLong(getMaskByMaskBit(maskBit)); + return getBeginIpLong(ip, maskBit) + ~MaskBit.getMaskIpLong(maskBit); } /** @@ -352,13 +361,24 @@ public class Ipv4Util { public static int countByIpRange(final String fromIp, final String toIp) { final long toIpLong = ipv4ToLong(toIp); final long fromIpLong = ipv4ToLong(fromIp); - Assert.isTrue(fromIpLong <= toIpLong, "Start IP must be less than or equal to end IP!"); + return countByIpRange(fromIpLong, toIpLong); + } + + /** + * 获得 指定区间内的 ip数量 + * + * @param fromIp 开始IP,包含 + * @param toIp 结束IP,包含 + * @return IP数量 + */ + public static int countByIpRange(final long fromIp, final long toIp) { + Assert.isTrue(fromIp <= toIp, "Start IP must be less than or equal to end IP!"); int count = 1; - count += (getPartOfIpLong(toIpLong, 4) - getPartOfIpLong(fromIpLong, 4)); - count += (getPartOfIpLong(toIpLong, 3) - getPartOfIpLong(fromIpLong, 3)) << 8; - count += (getPartOfIpLong(toIpLong, 2) - getPartOfIpLong(fromIpLong, 2)) << 16; - count += (getPartOfIpLong(toIpLong, 1) - getPartOfIpLong(fromIpLong, 1)) << 24; + count += (getPartOfIpLong(toIp, 4) - getPartOfIpLong(fromIp, 4)); + count += (getPartOfIpLong(toIp, 3) - getPartOfIpLong(fromIp, 3)) << 8; + count += (getPartOfIpLong(toIp, 2) - getPartOfIpLong(fromIp, 2)) << 16; + count += (getPartOfIpLong(toIp, 1) - getPartOfIpLong(fromIp, 1)) << 24; return count; } diff --git a/hutool-core/src/main/java/cn/hutool/core/net/MaskBit.java b/hutool-core/src/main/java/cn/hutool/core/net/MaskBit.java index 8e2cccc22..5b51c0c10 100644 --- a/hutool-core/src/main/java/cn/hutool/core/net/MaskBit.java +++ b/hutool-core/src/main/java/cn/hutool/core/net/MaskBit.java @@ -1,5 +1,6 @@ package cn.hutool.core.net; +import cn.hutool.core.lang.Assert; import cn.hutool.core.map.BiMap; import java.util.HashMap; @@ -73,4 +74,15 @@ public class MaskBit { return MASK_BIT_MAP.getKey(mask); } + /** + * 根据掩码位获取掩码IP(Long型) + * + * @param maskBit 掩码位 + * @return 掩码IP(Long型) + * @since 6.0.0 + */ + public static long getMaskIpLong(final int maskBit) { + Assert.isTrue(MASK_BIT_MAP.containsKey(maskBit), "非法的掩码位数:{}", maskBit); + return -1L << (32 - maskBit); + } }