392 lines
10 KiB
Java
392 lines
10 KiB
Java
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;
|
||
};
|
||
/*private static Function<String, List<Integer>> _toIntSlice = (str) -> {
|
||
String[] strArr = str.trim().split("");
|
||
List<Integer> arr = new ArrayList<>(strArr.length);
|
||
for (int i = 0; i < strArr.length; 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;
|
||
}
|
||
|
||
// 任意两个小数相加 x: 0.1213, y: 0.981
|
||
/*private static String _add(String x, String y) {
|
||
List<Integer> xArr = _toIntSlice.apply(x.substring(2));
|
||
List<Integer> yArr = _toIntSlice.apply(y.substring(2));
|
||
|
||
|
||
String v = "";
|
||
int len = xArr.size() > yArr.size() ? xArr.size() : yArr.size();
|
||
int carry = 0;
|
||
for (int i = 0; i < len; i++) {
|
||
int a = xArr.size() > (len - i - 1) ? xArr.get(len - i - 1) : 0;
|
||
int b = yArr.size() > (len - i - 1) ? yArr.get(len - i - 1) : 0;
|
||
int _v = a + b + carry;
|
||
|
||
carry = _v / 10;
|
||
v = _v % 10 + v;
|
||
}
|
||
v = carry + v;
|
||
StringBuffer buf = new StringBuffer(v).insert(v.length() - len, ".");
|
||
|
||
return buf.toString();
|
||
}
|
||
|
||
// 任意两个数相加
|
||
public static String addx(String x, String y) {
|
||
String str = _add(x, y);
|
||
System.out.printf("%s + %s = %s \n", x, y, str);
|
||
|
||
return str;
|
||
}*/
|
||
}
|