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; }; /*private static Function> _toIntSlice = (str) -> { String[] strArr = str.trim().split(""); List 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 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; } // 任意两个小数相加 x: 0.1213, y: 0.981 /*private static String _add(String x, String y) { List xArr = _toIntSlice.apply(x.substring(2)); List 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; }*/ }