This commit is contained in:
Looly 2021-10-29 01:41:00 +08:00
parent c608f62f79
commit 8efae077ff
6 changed files with 66 additions and 23 deletions

View File

@ -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
-------------------------------------------------------------------------------------------------------------

View File

@ -32,9 +32,11 @@ public interface RegexPool {
*/
String GROUP_VAR = "\\$(\\d+)";
/**
* IP v4
* IP v4<br>
* 采用分组方式便于解析地址的每一个段
*/
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
*/

View File

@ -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
}

View File

@ -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);
}
/**

View File

@ -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");
}
}

View File

@ -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);
}
}