add Ipv4Util

This commit is contained in:
Looly 2020-08-24 17:07:46 +08:00
parent f7a3b08803
commit 0e049861ee
5 changed files with 365 additions and 438 deletions

View File

@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
# 5.4.1 (2020-08-20)
# 5.4.1 (2020-08-24)
### 新特性
* 【core 】 StrUtil增加firstNonXXX方法issue#1020@Github
@ -14,6 +14,7 @@
* 【core 】 增加PathUtil和FileNameUtil分离FileUtil中部分方法
* 【core 】 改造IndexedComparator增加InstanceComparator
* 【extra 】 增加CglibUtil
* 【extra 】 增加Ipv4Utilpr#161@Gitee
### Bug修复#
* 【poi 】 修复ExcelBase.isXlsx方法判断问题issue#I1S502@Gitee

View File

@ -1,14 +1,19 @@
package cn.hutool.core.net;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
/**
* IP地址工具类
* IPV4地址工具类
*
* <p>pr自https://gitee.com/loolly/hutool/pulls/161</p>
*
* @author ZhuKun
* @date 2020-08-21
* @since 5.4.1
*/
public class Ipv4Util {
/**
@ -64,7 +69,7 @@ public class Ipv4Util {
* @param ip IP地址
* @param maskBit 掩码位例如2432
* @param isAll true:全量地址false:可用地址
* @return
* @return 区间地址
*/
public static List<String> list(String ip, int maskBit, boolean isAll) {
List<String> list = new ArrayList<>();
@ -94,26 +99,21 @@ public class Ipv4Util {
*
* @param ipFrom 开始IP
* @param ipTo 结束IP
* @return
* @return 区间地址
*/
public static List<String> list(String ipFrom, String ipTo) {
List<String> ips = new ArrayList<>();
String[] ipfromd = ipFrom.split("\\.");
String[] iptod = ipTo.split("\\.");
int[] int_ipf = new int[4];
int[] int_ipt = new int[4];
for (int i = 0; i < 4; i++) {
int_ipf[i] = Integer.parseInt(ipfromd[i]);
int_ipt[i] = Integer.parseInt(iptod[i]);
}
for (int A = int_ipf[0]; A <= int_ipt[0]; A++) {
for (int B = (A == int_ipf[0] ? int_ipf[1] : 0); B <= (A == int_ipt[0] ? int_ipt[1]
: 255); B++) {
for (int C = (B == int_ipf[1] ? int_ipf[2] : 0); C <= (B == int_ipt[1] ? int_ipt[2]
: 255); C++) {
for (int D = (C == int_ipf[2] ? int_ipf[3] : 0); D <= (C == int_ipt[2] ? int_ipt[3]
: 255); D++) {
ips.add(A + "." + B + "." + C + "." + D);
final int[] ipf = Convert.convert(int[].class, StrUtil.splitToArray(ipFrom, '.'));
final int[] ipt = Convert.convert(int[].class, StrUtil.splitToArray(ipTo, '.'));
final List<String> ips = new ArrayList<>();
for (int a = ipf[0]; a <= ipt[0]; a++) {
for (int b = (a == ipf[0] ? ipf[1] : 0); b <= (a == ipt[0] ? ipt[1]
: 255); b++) {
for (int c = (b == ipf[1] ? ipf[2] : 0); c <= (b == ipt[1] ? ipt[2]
: 255); c++) {
for (int d = (c == ipf[2] ? ipf[3] : 0); d <= (c == ipt[2] ? ipt[3]
: 255); d++) {
ips.add(a + "." + b + "." + c + "." + d);
}
}
}
@ -122,50 +122,46 @@ public class Ipv4Util {
}
/**
* 把long类型的Ip转为一般Ip类型xx.xx.xx.xx
* 根据long值获取ip v4地址xx.xx.xx.xx
*
* @param ip
* @return
* @param longIP IP的long表示形式
* @return IP V4 地址
*/
public static String longIpToStr(Long ip) {
String s1 = String.valueOf((ip & 4278190080L) / 16777216L);
String s2 = String.valueOf((ip & 16711680L) / 65536L);
String s3 = String.valueOf((ip & 65280L) / 256L);
String s4 = String.valueOf(ip & 255L);
return s1 + "." + s2 + "." + s3 + "." + s4;
public static String longToIpv4(long longIP) {
final StringBuilder sb = StrUtil.builder();
// 直接右移24位
sb.append((longIP >>> 24));
sb.append(".");
// 将高8位置0然后右移16位
sb.append(((longIP & 0x00FFFFFF) >>> 16));
sb.append(".");
sb.append(((longIP & 0x0000FFFF) >>> 8));
sb.append(".");
sb.append((longIP & 0x000000FF));
return sb.toString();
}
/**
* 把xxx.xxx.xxx.xxx类型的转为long类型的IP
* 根据ip地址(xxx.xxx.xxx.xxx)计算出long型的数据
*
* @param ip 字符类型的IP
* @return
* @param strIP IP V4 地址
* @return long值
*/
public static Long strIpToLong(String ip) {
Long ipLong = 0L;
String ipTemp = ip;
ipLong = ipLong * 256
+ Long.parseLong(ipTemp.substring(0, ipTemp.indexOf(".")));
ipTemp = ipTemp.substring(ipTemp.indexOf(".") + 1);
ipLong = ipLong * 256
+ Long.parseLong(ipTemp.substring(0, ipTemp.indexOf(".")));
ipTemp = ipTemp.substring(ipTemp.indexOf(".") + 1);
ipLong = ipLong * 256
+ Long.parseLong(ipTemp.substring(0, ipTemp.indexOf(".")));
ipTemp = ipTemp.substring(ipTemp.indexOf(".") + 1);
ipLong = ipLong * 256 + Long.parseLong(ipTemp);
return ipLong;
public static long ipv4ToLong(String strIP) {
if (Validator.isIpv4(strIP)) {
long[] ip = new long[4];
// 先找到IP地址字符串中.的位置
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];
}
/**
* 根据掩码位获取掩码
*
* @param maskBit 掩码位数"28""30"
* @return
*/
public static String getMaskByMaskBit(String maskBit) {
return StrUtil.isEmpty(maskBit) ? "error, maskBit is null !"
: maskBitMap().get(maskBit);
return 0;
}
/**
@ -176,7 +172,7 @@ public class Ipv4Util {
* @return 起始IP的字符串表示
*/
public static String getBeginIpStr(String ip, int maskBit) {
return longIpToStr(getBeginIpLong(ip, maskBit));
return longToIpv4(getBeginIpLong(ip, maskBit));
}
/**
@ -187,7 +183,7 @@ public class Ipv4Util {
* @return 起始IP的长整型表示
*/
private static Long getBeginIpLong(String ip, int maskBit) {
return strIpToLong(ip) & strIpToLong(getMaskByMaskBit(maskBit));
return ipv4ToLong(ip) & ipv4ToLong(getMaskByMaskBit(maskBit));
}
/**
@ -198,23 +194,9 @@ public class Ipv4Util {
* @return 终止IP的字符串表示
*/
public static String getEndIpStr(String ip, int maskBit) {
return longIpToStr(getEndIpLong(ip, maskBit));
return longToIpv4(getEndIpLong(ip, maskBit));
}
/**
* 根据 ip/掩码位 计算IP段的终止IPLong型
* 此接口返回负数请使用转成字符串后再转Long型
*
* @param ip 给定的IP如218.240.38.69
* @param maskBit 给定的掩码位如30
* @return 终止IP的长整型表示
*/
private static Long getEndIpLong(String ip, int maskBit) {
return getBeginIpLong(ip, maskBit)
+ ~strIpToLong(getMaskByMaskBit(maskBit));
}
/**
* 根据子网掩码转换为掩码位
*
@ -224,10 +206,10 @@ public class Ipv4Util {
public static int getMaskBitByMask(String mask) {
StringBuffer sbf;
String str;
int inetmask = 0, count = 0;
String[] ipList = mask.split("\\.");
for (int n = 0; n < ipList.length; n++) {
sbf = toBin(Integer.parseInt(ipList[n]));
int inetmask = 0;
int count;
for (String s : StrUtil.split(mask, ',')) {
sbf = toBin(Integer.parseInt(s));
str = sbf.reverse().toString();
count = 0;
for (int i = 0; i < str.length(); i++) {
@ -262,134 +244,14 @@ public class Ipv4Util {
}
}
private static StringBuffer toBin(int x) {
StringBuffer result = new StringBuffer();
result.append(x % 2);
x /= 2;
while (x > 0) {
result.append(x % 2);
x /= 2;
}
return result;
}
/**
* 存储着所有的掩码位及对应的掩码 key:掩码位 value:掩码x.x.x.x
*
* @return
*/
private static Map<String, String> maskBitMap() {
Map<String, String> maskBit = new HashMap<>(32);
maskBit.put("1", "128.0.0.0");
maskBit.put("2", "192.0.0.0");
maskBit.put("3", "224.0.0.0");
maskBit.put("4", "240.0.0.0");
maskBit.put("5", "248.0.0.0");
maskBit.put("6", "252.0.0.0");
maskBit.put("7", "254.0.0.0");
maskBit.put("8", "255.0.0.0");
maskBit.put("9", "255.128.0.0");
maskBit.put("10", "255.192.0.0");
maskBit.put("11", "255.224.0.0");
maskBit.put("12", "255.240.0.0");
maskBit.put("13", "255.248.0.0");
maskBit.put("14", "255.252.0.0");
maskBit.put("15", "255.254.0.0");
maskBit.put("16", "255.255.0.0");
maskBit.put("17", "255.255.128.0");
maskBit.put("18", "255.255.192.0");
maskBit.put("19", "255.255.224.0");
maskBit.put("20", "255.255.240.0");
maskBit.put("21", "255.255.248.0");
maskBit.put("22", "255.255.252.0");
maskBit.put("23", "255.255.254.0");
maskBit.put("24", "255.255.255.0");
maskBit.put("25", "255.255.255.128");
maskBit.put("26", "255.255.255.192");
maskBit.put("27", "255.255.255.224");
maskBit.put("28", "255.255.255.240");
maskBit.put("29", "255.255.255.248");
maskBit.put("30", "255.255.255.252");
maskBit.put("31", "255.255.255.254");
maskBit.put("32", "255.255.255.255");
return maskBit;
}
/**
* 根据掩码位获取掩码
*
* @param maskBit
* @return
* @param maskBit 掩码位
* @return 掩码
*/
public static String getMaskByMaskBit(int maskBit) {
switch (maskBit) {
case 1:
return "128.0.0.0";
case 2:
return "192.0.0.0";
case 3:
return "224.0.0.0";
case 4:
return "240.0.0.0";
case 5:
return "248.0.0.0";
case 6:
return "252.0.0.0";
case 7:
return "254.0.0.0";
case 8:
return "255.0.0.0";
case 9:
return "255.128.0.0";
case 10:
return "255.192.0.0";
case 11:
return "255.224.0.0";
case 12:
return "255.240.0.0";
case 13:
return "255.248.0.0";
case 14:
return "255.252.0.0";
case 15:
return "255.254.0.0";
case 16:
return "255.255.0.0";
case 17:
return "255.255.128.0";
case 18:
return "255.255.192.0";
case 19:
return "255.255.224.0";
case 20:
return "255.255.240.0";
case 21:
return "255.255.248.0";
case 22:
return "255.255.252.0";
case 23:
return "255.255.254.0";
case 24:
return "255.255.255.0";
case 25:
return "255.255.255.128";
case 26:
return "255.255.255.192";
case 27:
return "255.255.255.224";
case 28:
return "255.255.255.240";
case 29:
return "255.255.255.248";
case 30:
return "255.255.255.252";
case 31:
return "255.255.255.254";
case 32:
return "255.255.255.255";
default:
return "";
}
return MaskBit.get(maskBit);
}
/**
@ -398,16 +260,15 @@ public class Ipv4Util {
* @param fromIp 开始IP
* @param toIp 结束IP
* @return 掩码x.x.x.x
* @throws Exception
*/
public static String getMaskByIpRange(String fromIp, String toIp) throws Exception {
Long toIpLong = strIpToLong(toIp);
Long fromIpLong = strIpToLong(fromIp);
public static String getMaskByIpRange(String fromIp, String toIp) {
long toIpLong = ipv4ToLong(toIp);
long fromIpLong = ipv4ToLong(fromIp);
if (fromIpLong > toIpLong) {
throw new Exception("开始IP大与结束IP");
throw new IllegalArgumentException("to IP must be greater than from IP!");
}
String[] fromIpSplit = fromIp.split("\\.");
String[] toIpSplit = toIp.split("\\.");
String[] fromIpSplit = StrUtil.splitToArray(fromIp, '.');
String[] toIpSplit = StrUtil.splitToArray(toIp, '.');
StringBuilder mask = new StringBuilder();
for (int i = 0; i < toIpSplit.length; i++) {
mask.append(255 - Integer.parseInt(toIpSplit[i]) + Integer.parseInt(fromIpSplit[i])).append(".");
@ -421,20 +282,46 @@ public class Ipv4Util {
* @param fromIp 开始IP
* @param toIp 结束IP
* @return IP数量
* @throws Exception
*/
public static int countByIpRange(String fromIp, String toIp) throws Exception {
Long toIpLong = strIpToLong(toIp);
Long fromIpLong = strIpToLong(fromIp);
public static int countByIpRange(String fromIp, String toIp) {
long toIpLong = ipv4ToLong(toIp);
long fromIpLong = ipv4ToLong(fromIp);
if (fromIpLong > toIpLong) {
throw new Exception("开始IP大与结束IP");
throw new IllegalArgumentException("to IP must be greater than from IP!");
}
int count = 1;
int[] fromIpSplit = Arrays.stream(fromIp.split("\\.")).mapToInt(Integer::parseInt).toArray();
int[] toIpSplit = Arrays.stream(toIp.split("\\.")).mapToInt(Integer::parseInt).toArray();
int[] fromIpSplit = StrUtil.split(fromIp, '.').stream().mapToInt(Integer::parseInt).toArray();
int[] toIpSplit = StrUtil.split(toIp, '.').stream().mapToInt(Integer::parseInt).toArray();
for (int i = fromIpSplit.length - 1; i >= 0; i--) {
count += (toIpSplit[i] - fromIpSplit[i]) * Math.pow(256, fromIpSplit.length - i - 1);
}
return count;
}
//-------------------------------------------------------------------------------- Private method start
/**
* 根据 ip/掩码位 计算IP段的终止IPLong型
* 此接口返回负数请使用转成字符串后再转Long型
*
* @param ip 给定的IP如218.240.38.69
* @param maskBit 给定的掩码位如30
* @return 终止IP的长整型表示
*/
private static Long getEndIpLong(String ip, int maskBit) {
return getBeginIpLong(ip, maskBit)
+ ~ipv4ToLong(getMaskByMaskBit(maskBit));
}
private static StringBuffer toBin(int x) {
StringBuffer result = new StringBuffer();
result.append(x % 2);
x /= 2;
while (x > 0) {
result.append(x % 2);
x /= 2;
}
return result;
}
//-------------------------------------------------------------------------------- Private method end
}

View File

@ -0,0 +1,60 @@
package cn.hutool.core.net;
import java.util.HashMap;
import java.util.Map;
/**
* 掩码位和掩码之间的Map对应
*
* @since 5.4.1
* @author looly
*/
public class MaskBit {
private static final Map<Integer, String> maskBitMap;
static {
maskBitMap = new HashMap<>(32);
maskBitMap.put(1, "128.0.0.0");
maskBitMap.put(2, "192.0.0.0");
maskBitMap.put(3, "224.0.0.0");
maskBitMap.put(4, "240.0.0.0");
maskBitMap.put(5, "248.0.0.0");
maskBitMap.put(6, "252.0.0.0");
maskBitMap.put(7, "254.0.0.0");
maskBitMap.put(8, "255.0.0.0");
maskBitMap.put(9, "255.128.0.0");
maskBitMap.put(10, "255.192.0.0");
maskBitMap.put(11, "255.224.0.0");
maskBitMap.put(12, "255.240.0.0");
maskBitMap.put(13, "255.248.0.0");
maskBitMap.put(14, "255.252.0.0");
maskBitMap.put(15, "255.254.0.0");
maskBitMap.put(16, "255.255.0.0");
maskBitMap.put(17, "255.255.128.0");
maskBitMap.put(18, "255.255.192.0");
maskBitMap.put(19, "255.255.224.0");
maskBitMap.put(20, "255.255.240.0");
maskBitMap.put(21, "255.255.248.0");
maskBitMap.put(22, "255.255.252.0");
maskBitMap.put(23, "255.255.254.0");
maskBitMap.put(24, "255.255.255.0");
maskBitMap.put(25, "255.255.255.128");
maskBitMap.put(26, "255.255.255.192");
maskBitMap.put(27, "255.255.255.224");
maskBitMap.put(28, "255.255.255.240");
maskBitMap.put(29, "255.255.255.248");
maskBitMap.put(30, "255.255.255.252");
maskBitMap.put(31, "255.255.255.254");
maskBitMap.put(32, "255.255.255.255");
}
/**
* 根据掩码位获取掩码
*
* @param maskBit 掩码位
* @return 掩码
*/
public static String get(int maskBit) {
return maskBitMap.get(maskBit);
}
}

View File

@ -5,7 +5,6 @@ import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
@ -58,19 +57,10 @@ public class NetUtil {
*
* @param longIP IP的long表示形式
* @return IP V4 地址
* @see Ipv4Util#longToIpv4(long)
*/
public static String longToIpv4(long longIP) {
final StringBuilder sb = StrUtil.builder();
// 直接右移24位
sb.append((longIP >>> 24));
sb.append(".");
// 将高8位置0然后右移16位
sb.append(((longIP & 0x00FFFFFF) >>> 16));
sb.append(".");
sb.append(((longIP & 0x0000FFFF) >>> 8));
sb.append(".");
sb.append((longIP & 0x000000FF));
return sb.toString();
return Ipv4Util.longToIpv4(longIP);
}
/**
@ -78,22 +68,10 @@ public class NetUtil {
*
* @param strIP IP V4 地址
* @return long值
* @see Ipv4Util#ipv4ToLong(String)
*/
public static long ipv4ToLong(String strIP) {
if (Validator.isIpv4(strIP)) {
long[] ip = new long[4];
// 先找到IP地址字符串中.的位置
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;
return Ipv4Util.ipv4ToLong(strIP);
}
/**

View File

@ -96,6 +96,7 @@ public class ThreadUtil {
* @param maximumPoolSize 最大线程池大小
* @param maximumQueueSize 最大任务队列大小
* @return {@link ThreadPoolExecutor}
* @since 5.4.1
*/
public static ExecutorService newExecutor(int corePoolSize, int maximumPoolSize, int maximumQueueSize) {
return ExecutorBuilder.create()