fix Ipv4Util bug

This commit is contained in:
Looly 2020-11-09 03:45:21 +08:00
parent b8adadda38
commit 552750da15
7 changed files with 156 additions and 102 deletions

View File

@ -14,6 +14,9 @@
### Bug修复 ### Bug修复
* 【core 】 修复DateUtil.current使用System.nanoTime的问题issue#1198@Github * 【core 】 修复DateUtil.current使用System.nanoTime的问题issue#1198@Github
* 【core 】 修复Excel03SaxReader判断日期出错问题issue#I23M9H@Gitee * 【core 】 修复Excel03SaxReader判断日期出错问题issue#I23M9H@Gitee
* 【core 】 修复ClassUtil.getTypeArgument方法在判断泛型时导致的问题issue#1207@Github
* 【core 】 修复Ipv4Util分隔符问题issue#I24A9I@Gitee
* 【core 】 修复Ipv4Util.longToIp的问题
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@ -1,26 +1,39 @@
package cn.hutool.core.convert.impl; package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter; import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ClassLoaderUtil;
/** /**
* 类转换器<br> * 类转换器<br>
* 将类名转换为类 * 将类名转换为类默认初始化这个类执行static块
* @author Looly
* *
* @author Looly
*/ */
public class ClassConverter extends AbstractConverter<Class<?>>{ public class ClassConverter extends AbstractConverter<Class<?>> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final boolean isInitialized;
/**
* 构造
*/
public ClassConverter() {
this(true);
}
/**
* 构造
*
* @param isInitialized 是否初始化类调用static模块内容和初始化static属性
* @since 5.5.0
*/
public ClassConverter(boolean isInitialized) {
this.isInitialized = isInitialized;
}
@Override @Override
protected Class<?> convertInternal(Object value) { protected Class<?> convertInternal(Object value) {
String valueStr = convertToStr(value); return ClassLoaderUtil.loadClass(convertToStr(value), isInitialized);
try {
return ClassUtil.getClassLoader().loadClass(valueStr);
} catch (Exception e) {
// Ignore Exception
}
return null;
} }
} }

View File

@ -1,11 +1,15 @@
package cn.hutool.core.net; package cn.hutool.core.net;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator; import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* IPV4地址工具类 * IPV4地址工具类
@ -24,7 +28,7 @@ public class Ipv4Util {
/** /**
* IP与掩码的分割符 * IP与掩码的分割符
*/ */
public static final String IP_MASK_SPLIT_MARK = "/"; public static final String IP_MASK_SPLIT_MARK = StrUtil.SLASH;
/** /**
* 最大掩码位 * 最大掩码位
@ -51,15 +55,15 @@ public class Ipv4Util {
*/ */
public static List<String> list(String ipRange, boolean isAll) { public static List<String> list(String ipRange, boolean isAll) {
if (ipRange.contains(IP_SPLIT_MARK)) { if (ipRange.contains(IP_SPLIT_MARK)) {
String[] range = ipRange.split(IP_SPLIT_MARK); // X.X.X.X-X.X.X.X
final String[] range = StrUtil.split(ipRange, IP_SPLIT_MARK);
return list(range[0], range[1]); return list(range[0], range[1]);
} else if (ipRange.contains(IP_MASK_SPLIT_MARK)) { } else if (ipRange.contains(IP_MASK_SPLIT_MARK)) {
String[] param = ipRange.split(IP_MASK_SPLIT_MARK); // X.X.X.X/X
final String[] param = StrUtil.split(ipRange, IP_MASK_SPLIT_MARK);
return list(param[0], Integer.parseInt(param[1]), isAll); return list(param[0], Integer.parseInt(param[1]), isAll);
} else { } else {
List<String> ips = new ArrayList<>(); return ListUtil.toList(ipRange);
ips.add(ipRange);
return ips;
} }
} }
@ -72,26 +76,27 @@ public class Ipv4Util {
* @return 区间地址 * @return 区间地址
*/ */
public static List<String> list(String ip, int maskBit, boolean isAll) { public static List<String> list(String ip, int maskBit, boolean isAll) {
List<String> list = new ArrayList<>();
if (maskBit == IP_MASK_MAX) { if (maskBit == IP_MASK_MAX) {
if (Boolean.TRUE.equals(isAll)) { final List<String> list = new ArrayList<>();
if (isAll) {
list.add(ip); list.add(ip);
} }
} else { return list;
String startIp = getBeginIpStr(ip, maskBit);
String endIp = getEndIpStr(ip, maskBit);
String subStart = startIp.split("\\.")[0] + "." + startIp.split("\\.")[1] + "." + startIp.split("\\.")[2] + ".";
String subEnd = endIp.split("\\.")[0] + "." + endIp.split("\\.")[1] + "." + endIp.split("\\.")[2] + ".";
if (Boolean.TRUE.equals(isAll)) {
startIp = subStart + (Integer.parseInt(startIp.split("\\.")[3]));
endIp = subEnd + (Integer.parseInt(endIp.split("\\.")[3]));
} else {
startIp = subStart + (Integer.parseInt(startIp.split("\\.")[3]) + 1);
endIp = subEnd + (Integer.parseInt(endIp.split("\\.")[3]) - 1);
}
list = list(startIp, endIp);
} }
return list;
String startIp = getBeginIpStr(ip, maskBit);
String endIp = getEndIpStr(ip, maskBit);
if (isAll) {
return list(startIp, endIp);
}
int lastDotIndex = startIp.lastIndexOf(CharUtil.DOT) + 1;
startIp = StrUtil.subPre(startIp, lastDotIndex) +
(Integer.parseInt(Objects.requireNonNull(StrUtil.subSuf(startIp, lastDotIndex))) + 1);
lastDotIndex = endIp.lastIndexOf(CharUtil.DOT) + 1;
endIp = StrUtil.subPre(endIp, lastDotIndex) +
(Integer.parseInt(Objects.requireNonNull(StrUtil.subSuf(endIp, lastDotIndex))) - 1);
return list(startIp, endIp);
} }
/** /**
@ -102,8 +107,8 @@ public class Ipv4Util {
* @return 区间地址 * @return 区间地址
*/ */
public static List<String> list(String ipFrom, String ipTo) { public static List<String> list(String ipFrom, String ipTo) {
final int[] ipf = Convert.convert(int[].class, StrUtil.splitToArray(ipFrom, '.')); final int[] ipf = Convert.convert(int[].class, StrUtil.splitToArray(ipFrom, CharUtil.DOT));
final int[] ipt = Convert.convert(int[].class, StrUtil.splitToArray(ipTo, '.')); final int[] ipt = Convert.convert(int[].class, StrUtil.splitToArray(ipTo, CharUtil.DOT));
final List<String> ips = new ArrayList<>(); final List<String> ips = new ArrayList<>();
for (int a = ipf[0]; a <= ipt[0]; a++) { for (int a = ipf[0]; a <= ipt[0]; a++) {
@ -130,14 +135,14 @@ public class Ipv4Util {
public static String longToIpv4(long longIP) { public static String longToIpv4(long longIP) {
final StringBuilder sb = StrUtil.builder(); final StringBuilder sb = StrUtil.builder();
// 直接右移24位 // 直接右移24位
sb.append((longIP >>> 24)); sb.append(longIP >> 24 & 0xFF);
sb.append("."); sb.append(CharUtil.DOT);
// 将高8位置0然后右移16位 // 将高8位置0然后右移16位
sb.append(((longIP & 0x00FFFFFF) >>> 16)); sb.append(longIP >> 16 & 0xFF);
sb.append("."); sb.append(CharUtil.DOT);
sb.append(((longIP & 0x0000FFFF) >>> 8)); sb.append(longIP >> 8 & 0xFF);
sb.append("."); sb.append(CharUtil.DOT);
sb.append((longIP & 0x000000FF)); sb.append(longIP & 0xFF);
return sb.toString(); return sb.toString();
} }
@ -148,20 +153,9 @@ public class Ipv4Util {
* @return long值 * @return long值
*/ */
public static long ipv4ToLong(String strIP) { public static long ipv4ToLong(String strIP) {
if (Validator.isIpv4(strIP)) { Validator.validateIpv4(strIP, "Invalid IPv4 address!");
long[] ip = new long[4]; final long[] ip = Convert.convert(long[].class, StrUtil.split(strIP, CharUtil.DOT));
// 先找到IP地址字符串中.的位置 return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
int position1 = strIP.indexOf(".");
int position2 = strIP.indexOf(".", position1 + 1);
int position3 = strIP.indexOf(".", position2 + 1);
// 将每个.之间的字符串转换成整型
ip[0] = Long.parseLong(strIP.substring(0, position1));
ip[1] = Long.parseLong(strIP.substring(position1 + 1, position2));
ip[2] = Long.parseLong(strIP.substring(position2 + 1, position3));
ip[3] = Long.parseLong(strIP.substring(position3 + 1));
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
}
return 0;
} }
/** /**
@ -208,8 +202,8 @@ public class Ipv4Util {
String str; String str;
int inetmask = 0; int inetmask = 0;
int count; int count;
for (String s : StrUtil.split(mask, ',')) { for (String part : StrUtil.split(mask, CharUtil.DOT)) {
sbf = toBin(Integer.parseInt(s)); sbf = toBin(Integer.parseInt(part));
str = sbf.reverse().toString(); str = sbf.reverse().toString();
count = 0; count = 0;
for (int i = 0; i < str.length(); i++) { for (int i = 0; i < str.length(); i++) {
@ -233,15 +227,12 @@ public class Ipv4Util {
*/ */
public static int countByMaskBit(int maskBit, boolean isAll) { public static int countByMaskBit(int maskBit, boolean isAll) {
//如果是可用地址的情况掩码位小于等于0或大于等于32则可用地址为0 //如果是可用地址的情况掩码位小于等于0或大于等于32则可用地址为0
boolean isZero = !isAll && (maskBit <= 0 || maskBit >= 32); if ((false == isAll) && (maskBit <= 0 || maskBit >= 32)) {
if (isZero) {
return 0; return 0;
} }
if (isAll) {
return (int) Math.pow(2, 32 - maskBit); final int count = (int) Math.pow(2, 32 - maskBit);
} else { return isAll ? count : count - 2;
return (int) Math.pow(2, 32 - maskBit) - 2;
}
} }
/** /**
@ -264,14 +255,13 @@ public class Ipv4Util {
public static String getMaskByIpRange(String fromIp, String toIp) { public static String getMaskByIpRange(String fromIp, String toIp) {
long toIpLong = ipv4ToLong(toIp); long toIpLong = ipv4ToLong(toIp);
long fromIpLong = ipv4ToLong(fromIp); long fromIpLong = ipv4ToLong(fromIp);
if (fromIpLong > toIpLong) { Assert.isTrue(fromIpLong < toIpLong, "to IP must be greater than from IP!");
throw new IllegalArgumentException("to IP must be greater than from IP!");
} String[] fromIpSplit = StrUtil.splitToArray(fromIp, CharUtil.DOT);
String[] fromIpSplit = StrUtil.splitToArray(fromIp, '.'); String[] toIpSplit = StrUtil.splitToArray(toIp, CharUtil.DOT);
String[] toIpSplit = StrUtil.splitToArray(toIp, '.');
StringBuilder mask = new StringBuilder(); StringBuilder mask = new StringBuilder();
for (int i = 0; i < toIpSplit.length; i++) { for (int i = 0; i < toIpSplit.length; i++) {
mask.append(255 - Integer.parseInt(toIpSplit[i]) + Integer.parseInt(fromIpSplit[i])).append("."); mask.append(255 - Integer.parseInt(toIpSplit[i]) + Integer.parseInt(fromIpSplit[i])).append(CharUtil.DOT);
} }
return mask.substring(0, mask.length() - 1); return mask.substring(0, mask.length() - 1);
} }
@ -290,8 +280,8 @@ public class Ipv4Util {
throw new IllegalArgumentException("to IP must be greater than from IP!"); throw new IllegalArgumentException("to IP must be greater than from IP!");
} }
int count = 1; int count = 1;
int[] fromIpSplit = StrUtil.split(fromIp, '.').stream().mapToInt(Integer::parseInt).toArray(); int[] fromIpSplit = StrUtil.split(fromIp, CharUtil.DOT).stream().mapToInt(Integer::parseInt).toArray();
int[] toIpSplit = StrUtil.split(toIp, '.').stream().mapToInt(Integer::parseInt).toArray(); int[] toIpSplit = StrUtil.split(toIp, CharUtil.DOT).stream().mapToInt(Integer::parseInt).toArray();
for (int i = fromIpSplit.length - 1; i >= 0; i--) { for (int i = fromIpSplit.length - 1; i >= 0; i--) {
count += (toIpSplit[i] - fromIpSplit[i]) * Math.pow(256, fromIpSplit.length - i - 1); count += (toIpSplit[i] - fromIpSplit[i]) * Math.pow(256, fromIpSplit.length - i - 1);
} }

View File

@ -950,10 +950,7 @@ public class ClassUtil {
*/ */
public static Class<?> getTypeArgument(Class<?> clazz, int index) { public static Class<?> getTypeArgument(Class<?> clazz, int index) {
final Type argumentType = TypeUtil.getTypeArgument(clazz, index); final Type argumentType = TypeUtil.getTypeArgument(clazz, index);
if (argumentType instanceof Class) { return TypeUtil.getClass(argumentType);
return (Class<?>) argumentType;
}
return null;
} }
/** /**

View File

@ -1972,45 +1972,45 @@ public class StrUtil {
* abcdefgh 2 -3 = cde <br> * abcdefgh 2 -3 = cde <br>
* *
* @param str String * @param str String
* @param fromIndex 开始的index包括 * @param fromIndexInclude 开始的index包括
* @param toIndex 结束的index不包括 * @param toIndexExclude 结束的index不包括
* @return 字串 * @return 字串
*/ */
public static String sub(CharSequence str, int fromIndex, int toIndex) { public static String sub(CharSequence str, int fromIndexInclude, int toIndexExclude) {
if (isEmpty(str)) { if (isEmpty(str)) {
return str(str); return str(str);
} }
int len = str.length(); int len = str.length();
if (fromIndex < 0) { if (fromIndexInclude < 0) {
fromIndex = len + fromIndex; fromIndexInclude = len + fromIndexInclude;
if (fromIndex < 0) { if (fromIndexInclude < 0) {
fromIndex = 0; fromIndexInclude = 0;
} }
} else if (fromIndex > len) { } else if (fromIndexInclude > len) {
fromIndex = len; fromIndexInclude = len;
} }
if (toIndex < 0) { if (toIndexExclude < 0) {
toIndex = len + toIndex; toIndexExclude = len + toIndexExclude;
if (toIndex < 0) { if (toIndexExclude < 0) {
toIndex = len; toIndexExclude = len;
} }
} else if (toIndex > len) { } else if (toIndexExclude > len) {
toIndex = len; toIndexExclude = len;
} }
if (toIndex < fromIndex) { if (toIndexExclude < fromIndexInclude) {
int tmp = fromIndex; int tmp = fromIndexInclude;
fromIndex = toIndex; fromIndexInclude = toIndexExclude;
toIndex = tmp; toIndexExclude = tmp;
} }
if (fromIndex == toIndex) { if (fromIndexInclude == toIndexExclude) {
return EMPTY; return EMPTY;
} }
return str.toString().substring(fromIndex, toIndex); return str.toString().substring(fromIndexInclude, toIndexExclude);
} }
/** /**
@ -2095,11 +2095,11 @@ public class StrUtil {
* 切割指定位置之前部分的字符串 * 切割指定位置之前部分的字符串
* *
* @param string 字符串 * @param string 字符串
* @param toIndex 切割到的位置不包括 * @param toIndexExclude 切割到的位置不包括
* @return 切割后的剩余的前半部分字符串 * @return 切割后的剩余的前半部分字符串
*/ */
public static String subPre(CharSequence string, int toIndex) { public static String subPre(CharSequence string, int toIndexExclude) {
return sub(string, 0, toIndex); return sub(string, 0, toIndexExclude);
} }
/** /**

View File

@ -238,6 +238,12 @@ public class ConvertTest {
Assert.assertEquals("[1, 2]", atomicLongArray.toString()); Assert.assertEquals("[1, 2]", atomicLongArray.toString());
} }
@Test
public void toClassTest(){
final Class<?> convert = Convert.convert(Class.class, "cn.hutool.core.convert.ConvertTest.Product");
Assert.assertEquals(Product.class, convert);
}
@Data @Data
@AllArgsConstructor @AllArgsConstructor
public static class Product implements Serializable { public static class Product implements Serializable {

View File

@ -0,0 +1,45 @@
package cn.hutool.core.net;
import cn.hutool.core.lang.Console;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class Ipv4UtilTest {
@Test
public void getMaskBitByMaskTest(){
final int maskBitByMask = Ipv4Util.getMaskBitByMask("255.255.255.0");
Assert.assertEquals(24, maskBitByMask);
}
@Test
public void getMaskByMaskBitTest(){
final String mask = Ipv4Util.getMaskByMaskBit(24);
Assert.assertEquals("255.255.255.0", mask);
}
@Test
public void longToIpTest() {
String ip = "192.168.1.255";
final long ipLong = Ipv4Util.ipv4ToLong(ip);
String ipv4 = Ipv4Util.longToIpv4(ipLong);
Assert.assertEquals(ip, ipv4);
}
@Test
public void getEndIpStrTest(){
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);
}
@Test
public void listTest(){
int maskBit = Ipv4Util.getMaskBitByMask("255.255.255.0");
final List<String> list = Ipv4Util.list("192.168.100.2", maskBit, false);
Assert.assertEquals(254, list.size());
}
}