From 560c07f3d2ebf54974ef2196180a7b347da214c1 Mon Sep 17 00:00:00 2001 From: lxyer <237809796@qq.com> Date: Mon, 24 Jun 2019 17:16:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EIpKit=20=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/net/tccn/base/IpKit.java | 352 +++++++++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 src/main/java/net/tccn/base/IpKit.java diff --git a/src/main/java/net/tccn/base/IpKit.java b/src/main/java/net/tccn/base/IpKit.java new file mode 100644 index 0000000..285d320 --- /dev/null +++ b/src/main/java/net/tccn/base/IpKit.java @@ -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> tmp = new ArrayList<>(); + + List xArr = new ArrayList<>(); + List 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 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 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 xArr = toIntSlice.apply(x); + List 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> toIntSlice = (str) -> { + String[] strArr = str.trim().split(""); + List 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 xArr = toIntSlice.apply(x); + List 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 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; + } +}