From 8efae077ff3b229e536fb35cd181289014dc9d8b Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 29 Oct 2021 01:41:00 +0800 Subject: [PATCH] fix bug --- CHANGELOG.md | 3 +- .../java/cn/hutool/core/lang/RegexPool.java | 6 ++-- .../java/cn/hutool/core/net/Ipv4Util.java | 35 ++++++++++++++----- .../main/java/cn/hutool/core/net/NetUtil.java | 17 ++++----- .../cn/hutool/core/lang/ValidatorTest.java | 11 +++++- .../java/cn/hutool/core/net/Ipv4UtilTest.java | 17 +++++++-- 6 files changed, 66 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index caba2aed1..1a0e56750 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.7.16 (2021-10-28) +# 5.7.16 (2021-10-29) ### 🐣新特性 * 【core 】 增加DateTime.toLocalDateTime @@ -22,6 +22,7 @@ * 【core 】 修复CharSequenceUtil.wrapIfMissing预定义长度计算问题(issue#I4FDZ2@Gitee) * 【poi 】 修复合并单元格为日期时,导出单元格数据为数字问题(issue#1911@Github) * 【core 】 修复CompilerUtil.getFileManager参数没有使用的问题(issue#I4FIO6@Gitee) +* 【core 】 修复NetUtil.isInRange的cidr判断问题(pr#1917@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java b/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java index d21b8523b..ed7f8cad6 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java @@ -32,9 +32,11 @@ public interface RegexPool { */ String GROUP_VAR = "\\$(\\d+)"; /** - * IP v4 + * IP v4
+ * 采用分组方式便于解析地址的每一个段 */ - String IPV4 = "\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b"; + //String IPV4 = "\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b"; + String IPV4 = "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)$"; /** * IP v6 */ 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 3b6ab8140..9b45795e6 100644 --- a/hutool-core/src/main/java/cn/hutool/core/net/Ipv4Util.java +++ b/hutool-core/src/main/java/cn/hutool/core/net/Ipv4Util.java @@ -3,13 +3,14 @@ package cn.hutool.core.net; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Assert; -import cn.hutool.core.lang.Validator; +import cn.hutool.core.lang.PatternPool; import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.StrUtil; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.regex.Matcher; /** * IPV4地址工具类 @@ -20,6 +21,7 @@ import java.util.Objects; * @since 5.4.1 */ public class Ipv4Util { + /** * IP段的分割符 */ @@ -149,18 +151,25 @@ public class Ipv4Util { /** * 根据ip地址(xxx.xxx.xxx.xxx)计算出long型的数据 * 方法别名:inet_aton + * * @param strIP IP V4 地址 * @return long值 */ public static long ipv4ToLong(String strIP) { - Validator.validateIpv4(strIP, "Invalid IPv4 address!"); - final long[] ip = Convert.convert(long[].class, StrUtil.split(strIP, CharUtil.DOT)); - return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; + final Matcher matcher = PatternPool.IPV4.matcher(strIP); + if (matcher.matches()) { + return matchAddress(matcher); + } +// Validator.validateIpv4(strIP, "Invalid IPv4 address!"); +// final long[] ip = Convert.convert(long[].class, StrUtil.split(strIP, CharUtil.DOT)); +// return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; + throw new IllegalArgumentException("Invalid IPv4 address!"); } /** * 根据 ip/掩码位 计算IP段的起始IP(字符串型) * 方法别名:inet_ntoa + * * @param ip 给定的IP,如218.240.38.69 * @param maskBit 给定的掩码位,如30 * @return 起始IP的字符串表示 @@ -195,9 +204,7 @@ public class Ipv4Util { * 根据子网掩码转换为掩码位 * * @param mask 掩码的点分十进制表示,例如 255.255.255.0 - * * @return 掩码位,例如 24 - * * @throws IllegalArgumentException 子网掩码非法 */ public static int getMaskBitByMask(String mask) { @@ -282,7 +289,6 @@ public class Ipv4Util { * 判断掩码是否合法 * * @param mask 掩码的点分十进制表示,例如 255.255.255.0 - * * @return true:掩码合法;false:掩码不合法 */ public static boolean isMaskValid(String mask) { @@ -293,7 +299,6 @@ public class Ipv4Util { * 判断掩码位是否合法 * * @param maskBit 掩码位,例如 24 - * * @return true:掩码位合法;false:掩码位不合法 */ public static boolean isMaskBitValid(int maskBit) { @@ -315,5 +320,19 @@ public class Ipv4Util { return getBeginIpLong(ip, maskBit) + ~ipv4ToLong(getMaskByMaskBit(maskBit)); } + + /** + * 将匹配到的Ipv4地址的4个分组分别处理 + * + * @param matcher 匹配到的Ipv4正则 + * @return ipv4对应long + */ + private static long matchAddress(Matcher matcher) { + long addr = 0; + for (int i = 1; i <= 4; ++i) { + addr |= Long.parseLong(matcher.group(i)) << 8 * (4 - i); + } + return addr; + } //-------------------------------------------------------------------------------- Private method end } diff --git a/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java b/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java index 65e521342..7758998e5 100644 --- a/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/net/NetUtil.java @@ -699,14 +699,15 @@ public class NetUtil { * @since 4.0.6 */ public static boolean isInRange(String ip, String cidr) { - String[] ips = StrUtil.splitToArray(ip, '.'); - int ipAddr = (Integer.parseInt(ips[0]) << 24) | (Integer.parseInt(ips[1]) << 16) | (Integer.parseInt(ips[2]) << 8) | Integer.parseInt(ips[3]); - int type = Integer.parseInt(cidr.replaceAll(".*/", "")); - int mask = (int)((-1L << 32 - type) & 0XFFFFFFFF); - String cidrIp = cidr.replaceAll("/.*", ""); - String[] cidrIps = cidrIp.split("\\."); - int cidrIpAddr = (Integer.parseInt(cidrIps[0]) << 24) | (Integer.parseInt(cidrIps[1]) << 16) | (Integer.parseInt(cidrIps[2]) << 8) | Integer.parseInt(cidrIps[3]); - return (ipAddr & mask) == (cidrIpAddr & mask); + final int maskSplitMarkIndex = cidr.lastIndexOf(Ipv4Util.IP_MASK_SPLIT_MARK); + if(maskSplitMarkIndex < 0){ + throw new IllegalArgumentException("Invalid cidr: " + cidr); + } + + final long mask = (-1L << 32 - Integer.parseInt(cidr.substring(maskSplitMarkIndex + 1))); + long cidrIpAddr = ipv4ToLong(cidr.substring(0, maskSplitMarkIndex)); + + return (ipv4ToLong(ip) & mask) == (cidrIpAddr & mask); } /** diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java index a14a3d8dd..cfcd7866f 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java @@ -21,7 +21,7 @@ public class ValidatorTest { } @Test - public void hasNumberTest() throws Exception { + public void hasNumberTest() { String var1 = ""; String var2 = "str"; String var3 = "180"; @@ -218,4 +218,13 @@ public class ValidatorTest { public void isCarDrivingLicenceTest(){ Assert.assertTrue(Validator.isCarDrivingLicence("430101758218")); } + + @Test + public void validateIpv4Test(){ + Validator.validateIpv4("192.168.1.1", "Error ip"); + Validator.validateIpv4("8.8.8.8", "Error ip"); + Validator.validateIpv4("0.0.0.0", "Error ip"); + Validator.validateIpv4("255.255.255.255", "Error ip"); + Validator.validateIpv4("127.0.0.0", "Error ip"); + } } diff --git a/hutool-core/src/test/java/cn/hutool/core/net/Ipv4UtilTest.java b/hutool-core/src/test/java/cn/hutool/core/net/Ipv4UtilTest.java index 5a472963c..13d5ddbd1 100644 --- a/hutool-core/src/test/java/cn/hutool/core/net/Ipv4UtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/net/Ipv4UtilTest.java @@ -1,11 +1,10 @@ package cn.hutool.core.net; -import cn.hutool.core.lang.Console; import org.junit.Assert; import org.junit.Test; +import org.junit.function.ThrowingRunnable; import java.util.List; -import org.junit.function.ThrowingRunnable; public class Ipv4UtilTest { @@ -40,7 +39,7 @@ public class Ipv4UtilTest { String ip = "192.168.1.1"; final int maskBitByMask = Ipv4Util.getMaskBitByMask("255.255.255.0"); final String endIpStr = Ipv4Util.getEndIpStr(ip, maskBitByMask); - Console.log(endIpStr); + Assert.assertEquals("192.168.1.255", endIpStr); } @Test @@ -75,4 +74,16 @@ public class Ipv4UtilTest { boolean maskBitValid = Ipv4Util.isMaskBitValid(33); Assert.assertFalse("掩码位非法检验", maskBitValid); } + + @Test + public void ipv4ToLongTest(){ + long l = Ipv4Util.ipv4ToLong("127.0.0.1"); + Assert.assertEquals(2130706433L, l); + l = Ipv4Util.ipv4ToLong("114.114.114.114"); + Assert.assertEquals(1920103026L, l); + l = Ipv4Util.ipv4ToLong("0.0.0.0"); + Assert.assertEquals(0L, l); + l = Ipv4Util.ipv4ToLong("255.255.255.255"); + Assert.assertEquals(4294967295L, l); + } }