Files
meta-kit/src/main/java/net/tccn/base/IpKit.java
2020-05-10 23:18:59 +08:00

392 lines
10 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}*/
}