新增IpKit 工具类
This commit is contained in:
352
src/main/java/net/tccn/base/IpKit.java
Normal file
352
src/main/java/net/tccn/base/IpKit.java
Normal file
@@ -0,0 +1,352 @@
|
||||
package net.tccn.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author: liangxianyou
|
||||
*/
|
||||
public class IpKit {
|
||||
|
||||
public static String toNum(String ip) {
|
||||
if (ip == null || ip.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
if (isV4(ip)) {
|
||||
return v4Num(ip) + "";
|
||||
} else {
|
||||
return v6Num(ip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* IP区间包含IP数计算,含首尾
|
||||
*
|
||||
* @param startIp 其实ip
|
||||
* @param endIp 结束ip
|
||||
* @return
|
||||
*/
|
||||
public static String ipCount(String startIp, String endIp) {
|
||||
if (startIp == null || startIp.isEmpty() || endIp == null || endIp.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
if (isV4(startIp, endIp)) {
|
||||
return v4Count(startIp, endIp) + "";
|
||||
} else {
|
||||
return v6Count(startIp, endIp);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isV4(String... ips) {
|
||||
for (String ip : ips) {
|
||||
String pattern = "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$";
|
||||
if (!Pattern.matches(pattern, ip)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*if (!ip.contains(".")) {
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------ ipv4 ----------------------------------
|
||||
|
||||
/**
|
||||
* ipv4 区间包含Ip数,含首尾
|
||||
*
|
||||
* @param startIp
|
||||
* @param endIp
|
||||
* @return
|
||||
*/
|
||||
private static String v4Count(String startIp, String endIp) {
|
||||
String start = v4Num(startIp);
|
||||
String end = v4Num(endIp);
|
||||
|
||||
String v = subtract(end, start);
|
||||
if (v.startsWith("-")) {
|
||||
v = v.substring(1);
|
||||
}
|
||||
v = add(v, "1");
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipv4转数值
|
||||
*
|
||||
* @param ip ipv4
|
||||
* @return
|
||||
*/
|
||||
private static String v4Num(String ip) {
|
||||
String[] ipArr = ip.trim().split("[.]");
|
||||
int[] vs = {16777216, 65536, 256, 1};
|
||||
String v = "0";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// v += vs[i] * Integer.parseInt(ipArr[i]);
|
||||
v = add(v, ride(vs[i] + "", ipArr[i]));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//------------------------------ ipv6 ----------------------------------
|
||||
|
||||
/**
|
||||
* ipv6 区间包含Ip数,含首尾
|
||||
*
|
||||
* @param startIp
|
||||
* @param endIp
|
||||
* @return
|
||||
*/
|
||||
private static String v6Count(String startIp, String endIp) {
|
||||
String start = v6Num(startIp);
|
||||
String end = v6Num(endIp);
|
||||
String subtract = subtract(start, end);
|
||||
if (subtract.startsWith("-")) {
|
||||
subtract = subtract.substring(1);
|
||||
}
|
||||
subtract = add(subtract, "1");
|
||||
return subtract;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将ipv6转为数值
|
||||
*
|
||||
* @param ip ipv6
|
||||
* @return ipv6 转换后的数值
|
||||
*/
|
||||
private static String v6Num(String ip) {
|
||||
ip = restoreV6(ip);
|
||||
|
||||
int[] ipArr = new int[8];
|
||||
String[] ipSlice = ip.split(":");
|
||||
|
||||
for (int i = 0; i < ipSlice.length; i++) {
|
||||
ipArr[i] = Integer.parseInt(ipSlice[i], 16);
|
||||
}
|
||||
|
||||
String[] baseNum = {
|
||||
"5192296858534827628530496329220096",
|
||||
"79228162514264337593543950336",
|
||||
"1208925819614629174706176",
|
||||
"18446744073709551616",
|
||||
"281474976710656",
|
||||
"4294967296",
|
||||
"65536",
|
||||
"1"};
|
||||
|
||||
|
||||
String v = "0";
|
||||
for (int i = 0; i < 8; i++) {
|
||||
v = add(v, ride(baseNum[i], ipArr[i] + ""));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
|
||||
/**
|
||||
* 两任意大小正整数相乘
|
||||
*
|
||||
* @param x 正整数 x
|
||||
* @param y 正整数 y
|
||||
* @return 返回乘积数字 字符串
|
||||
*/
|
||||
private static String ride(String x, String y) {
|
||||
List<List<Integer>> tmp = new ArrayList<>();
|
||||
|
||||
List<Integer> xArr = new ArrayList<>();
|
||||
List<Integer> yArr = new ArrayList<>();
|
||||
for (String s : String.valueOf(x).split("")) {
|
||||
xArr.add(Integer.parseInt(s));
|
||||
}
|
||||
for (String s : String.valueOf(y).split("")) {
|
||||
yArr.add(Integer.parseInt(s));
|
||||
}
|
||||
|
||||
//分步 相乘
|
||||
int z = 0;
|
||||
for (int i = xArr.size() - 1; i >= 0; i--, z++) {
|
||||
List<Integer> list = new ArrayList<>();
|
||||
for (int j = 0; j < z; j++) {
|
||||
list.add(0);
|
||||
}
|
||||
|
||||
int[] carry = {0};
|
||||
int a = xArr.get(i);
|
||||
for (int j = yArr.size() - 1; j >= 0; j--) {
|
||||
int b = yArr.get(j);
|
||||
list.add(a * b % 10 + carry[0]);
|
||||
carry[0] = a * b / 10;
|
||||
}
|
||||
if (carry[0] > 0) {
|
||||
list.add(carry[0]);
|
||||
}
|
||||
|
||||
tmp.add(list);
|
||||
}
|
||||
|
||||
//合并 相加
|
||||
String v = "";
|
||||
int carry = 0;
|
||||
boolean end = false;
|
||||
for (int i = 0; ; i++) {
|
||||
end = true;
|
||||
int _v = 0;
|
||||
for (int j = 0; j < tmp.size(); j++) {
|
||||
List<Integer> row = tmp.get(j);
|
||||
if (row.size() > i) {
|
||||
end = false;
|
||||
_v += row.get(i);
|
||||
}
|
||||
}
|
||||
if (end) {
|
||||
break;
|
||||
}
|
||||
|
||||
_v = carry + _v;
|
||||
v = _v % 10 + v;
|
||||
carry = _v / 10;
|
||||
}
|
||||
if (carry > 0) {
|
||||
v = carry + v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 两任意大小正整数 相加
|
||||
*
|
||||
* @param x 正整数 x
|
||||
* @param y 正整数 y
|
||||
* @return 返回两数之和 字符串
|
||||
*/
|
||||
private static String add(String x, String y) {
|
||||
List<Integer> xArr = toIntSlice.apply(x);
|
||||
List<Integer> yArr = toIntSlice.apply(y);
|
||||
|
||||
String v = "";
|
||||
int carry = 0;
|
||||
for (int i = 0; i < xArr.size() || i < yArr.size(); i++) {
|
||||
int a = i < xArr.size() ? xArr.get(i) : 0;
|
||||
int b = i < yArr.size() ? yArr.get(i) : 0;
|
||||
|
||||
int _v = a + b + carry;
|
||||
if (_v >= 10) {
|
||||
carry = 1;
|
||||
_v -= 10;
|
||||
} else {
|
||||
carry = 0;
|
||||
}
|
||||
v = _v + v;
|
||||
}
|
||||
if (carry > 0) {
|
||||
v = carry + v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
private static Function<String, List<Integer>> toIntSlice = (str) -> {
|
||||
String[] strArr = str.trim().split("");
|
||||
List<Integer> arr = new ArrayList<>();
|
||||
for (int i = strArr.length - 1; i >= 0; i--) {
|
||||
arr.add(Integer.parseInt(strArr[i]));
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
/**
|
||||
* 任意两个大小正整数相减
|
||||
*
|
||||
* @param x 正整数 x
|
||||
* @param y 正整数 y
|
||||
* @return x-y 的差
|
||||
*/
|
||||
private static String subtract(String x, String y) {
|
||||
List<Integer> xArr = toIntSlice.apply(x);
|
||||
List<Integer> yArr = toIntSlice.apply(y);
|
||||
|
||||
// 值大小比较
|
||||
boolean yThanX = xArr.size() < yArr.size();
|
||||
if (xArr.size() == yArr.size()) {
|
||||
for (int i = xArr.size() - 1; i >= 0; i--) {
|
||||
if (xArr.get(i) > yArr.get(i)) {
|
||||
yThanX = false;
|
||||
break;
|
||||
} else if (xArr.get(i) < yArr.get(i)) {
|
||||
yThanX = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yThanX) {
|
||||
List<Integer> tmp = xArr;
|
||||
xArr = yArr;
|
||||
yArr = tmp;
|
||||
}
|
||||
|
||||
// 计算
|
||||
String v = "";
|
||||
int subplus = 0; // 如:-1
|
||||
for (int i = 0; i < xArr.size(); i++) {
|
||||
int a = xArr.get(i);
|
||||
int b = yArr.size() > i ? yArr.get(i) : 0;
|
||||
|
||||
int _v = a - b + subplus;
|
||||
if (_v < 0) {
|
||||
subplus = -1;
|
||||
_v = _v + 10;
|
||||
} else {
|
||||
subplus = 0;
|
||||
}
|
||||
|
||||
v = _v + v;
|
||||
}
|
||||
// 去除首位0
|
||||
while (v.startsWith("0") && v.length() > 1) {
|
||||
v = v.substring(1);
|
||||
}
|
||||
if (yThanX) {
|
||||
v = "-" + v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipv6还原,去掉压缩写法
|
||||
*
|
||||
* @param ip 原始ipv6
|
||||
* @return 标准IPV6
|
||||
*/
|
||||
private static String restoreV6(String ip) {
|
||||
// 计算 :个数
|
||||
// 补全 省略的0
|
||||
String[] arr = ip.split("");
|
||||
int n = 0;
|
||||
for (String s : arr) {
|
||||
if (":".equals(s)) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
String _ip = ip;
|
||||
if (n < 7) {
|
||||
String b = "";
|
||||
for (int i = 0; i <= 7 - n; i++) {
|
||||
b += ":0";
|
||||
}
|
||||
b += ":";
|
||||
_ip = ip.replace("::", b);
|
||||
}
|
||||
if (_ip.startsWith(":")) {
|
||||
_ip = "0" + _ip;
|
||||
}
|
||||
if (_ip.endsWith(":")) {
|
||||
_ip = _ip + "0";
|
||||
}
|
||||
return _ip;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user