package mapreduce.nat; import java.math.BigDecimal; import java.math.BigInteger; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import job.Utilities; /** * 关于ip操作的工具类 * * @author hjb * */ public class IPV6Util { public static BigInteger ipv6ToBytesToBigInteger(String ipv6) { byte[] ret = new byte[17]; ret[0] = 0; int ib = 16; boolean comFlag = false;// ipv4混合模式标记 if (ipv6.startsWith(":"))// 去掉开头的冒号 ipv6 = ipv6.substring(1); if (ipv6.endsWith("::")) { ipv6 = ipv6+"0"; } String groups[] = ipv6.split(":"); for (int ig = groups.length - 1; ig > -1; ig--) {// 反向扫描 if (groups[ig].contains(".")) { // 出现ipv4混合模式 byte[] temp = ipv4ToBytes(groups[ig]); ret[ib--] = temp[4]; ret[ib--] = temp[3]; ret[ib--] = temp[2]; ret[ib--] = temp[1]; comFlag = true; } else if ("".equals(groups[ig])) { // 出现零长度压缩,计算缺少的组数 int zlg = 9 - (groups.length + (comFlag ? 1 : 0)); while (zlg-- > 0) {// 将这些组置0 ret[ib--] = 0; ret[ib--] = 0; } } else { int temp = Integer.parseInt(groups[ig], 16); ret[ib--] = (byte) temp; ret[ib--] = (byte) (temp >> 8); } } return new BigInteger(ret); } private static byte[] ipv4ToBytes(String ipv4) { byte[] ret = new byte[5]; ret[0] = 0; // 先找到IP地址字符串中.的位置 int position1 = ipv4.indexOf("."); int position2 = ipv4.indexOf(".", position1 + 1); int position3 = ipv4.indexOf(".", position2 + 1); // 将每个.之间的字符串转换成整型 ret[1] = (byte) Integer.parseInt(ipv4.substring(0, position1)); ret[2] = (byte) Integer.parseInt(ipv4.substring(position1 + 1, position2)); ret[3] = (byte) Integer.parseInt(ipv4.substring(position2 + 1, position3)); ret[4] = (byte) Integer.parseInt(ipv4.substring(position3 + 1)); return ret; } public static BigInteger[] convertList(String ip) { BigInteger[] arr = new BigInteger[2]; String tmpIp = ip.substring(0, ip.indexOf("/")); if (Utilities.isValidIP(tmpIp)) { Long[] ipToLong = Utilities.getIpLong(ip); arr[0] = BigInteger.valueOf(ipToLong[0]); arr[1] = BigInteger.valueOf(ipToLong[1]); } else if (Utilities.isValidIPv6(tmpIp)) { arr = IPV6Util.getIpv6Long(ip); } return arr; } public static BigInteger convertToBigInteger(String ip) throws Exception { BigInteger tmpBig = null; if (Utilities.isValidIP(ip)) { Long ipToLong1 = Utilities.ipToLong(ip); tmpBig = BigInteger.valueOf(ipToLong1); } else if (Utilities.isValidIPv6(ip)) { tmpBig = ipv6ToBytesToBigInteger(ip); } return tmpBig; } // 将ipv6地址转换为二进制分段(为了创造ip段写的) public static String fenduan(String ipv6) throws UnknownHostException { ipv6 = completIpv6(ipv6); String[] split = ipv6.split(":"); String tmpString = ""; if (split.length == 8) { for (int i = 0; i < split.length; i++) { String str = Long.toBinaryString(Long.valueOf(split[i], 16)); tmpString += str + " "; } } return tmpString; } public static String fenduan4(String ipv6) throws UnknownHostException { String[] split = ipv6.split("\\."); String tmpString = ""; if (split.length == 4) { for (int i = 0; i < split.length; i++) { String str = Long.toBinaryString(Long.valueOf(split[i])); tmpString += str + " "; } } return tmpString; } public static boolean isInRange(String ip, String cidr) { String[] ips = ip.split("\\."); int ipAddr = (Integer.parseInt(ips[0]) << 24) | (Integer.parseInt(ips[1]) << 16) | (Integer.parseInt(ips[2]) << 8) | Integer.parseInt(ips[3]); int type = Integer.parseInt(cidr.replaceAll(".*/", "")); int mask = 0xFFFFFFFF << (32 - type); String cidrIp = cidr.replaceAll("/.*", ""); String[] cidrIps = cidrIp.split("\\."); int cidrIpAddr = (Integer.parseInt(cidrIps[0]) << 24) | (Integer.parseInt(cidrIps[1]) << 16) | (Integer.parseInt(cidrIps[2]) << 8) | Integer.parseInt(cidrIps[3]); return (ipAddr & mask) == (cidrIpAddr & mask); } public static boolean isBelongIpv6(String ipv6, String ipv6area) throws Exception { // ipv6 = completIpv6(ipv6); int suffix = 0; if (ipv6area.contains("/")) { suffix = Integer.parseInt(ipv6area.substring(ipv6area.indexOf("/") + 1)); ipv6area = ipv6area.substring(0, ipv6area.indexOf("/")); } BigInteger ipv6Big = ipv6ToBytesToBigInteger(ipv6); BigInteger ipv6areaBig = ipv6ToBytesToBigInteger(ipv6area); BigDecimal ss = new BigDecimal(2); BigDecimal pow = ss.pow(128); BigInteger aa = new BigInteger(pow.toString()); String str = aa.toString(2).replaceAll("0", "1").substring(1); BigInteger bb = new BigInteger(str, 2); String str1 = bb.shiftLeft(128 - suffix).toString(2); String str2 = str1.substring(128 - suffix, str1.length()); BigInteger mask = new BigInteger(str2, 2); return ipv6Big.and(mask).compareTo(ipv6areaBig.and(mask)) == 0 ? true : false; } /** * 将ipv6每段补齐4位 * * @return * @throws UnknownHostException */ public static String completIpv6(String ipv6) throws UnknownHostException { StringBuffer str = new StringBuffer(); if (isValidIPv6(ipv6)) { String ip = InetAddress.getByName(ipv6).toString().replace("/", ""); String[] info = ip.split(":"); for (int i = 0; i < info.length; i++) { switch (info[i].length()) { case 1: info[i] = "000" + info[i]; break; case 2: info[i] = "00" + info[i]; break; case 3: info[i] = "0" + info[i]; break; default: break; } if (i < 7) { str.append(info[i] + ":"); } else { str.append(info[i]); } } } return str.toString(); } /** * 将ipv6地址转换为10进制 * * @throws Exception */ public static BigInteger ipv6ToBigInt(String ipv6) throws Exception { BigInteger numip = BigInteger.ZERO; String completIpv6 = completIpv6(ipv6); // String completIpv6 = ipv6; if (completIpv6.endsWith(":") && completIpv6.contains(".")) { completIpv6 = completIpv6.replace(":", ""); } if (isIpV4OrV6(completIpv6) == 4) { numip = BigInteger.valueOf(Utilities.ipToLong(completIpv6)); } else if (isIpV4OrV6(completIpv6) == 6) { String[] split = completIpv6.split(":"); for (int i = 0; i < split.length; i++) { numip = numip .add(BigInteger.valueOf(Long.parseLong(split[i], 16)).shiftLeft(16 * (split.length - i - 1))); } } return numip; } /** * 将整数形式的ipv6地址转换为字符串形式 * */ public static String int2ipv6(BigInteger big) { String str = ""; BigInteger ff = BigInteger.valueOf(0xffff); for (int i = 0; i < 8; i++) { str = big.and(ff).toString(16) + ":" + str; big = big.shiftRight(16); } str = str.substring(0, str.length() - 1); return str.replaceFirst("(^|:)(0+(:|$)){2,8}", "::"); } /** * 将ipv6地址压缩为最简模式 IPv6简写规范: 1) 每个IPv6地址段起始的0可以被省略; 2) 如果一段为4个零,可以简写为一个0 3) * 如果有连续的多个段全为0,则可以使用::表示 注:一个地址段中只能有一个::出现,不可以出现两个及以上 */ public static String ipv6Shorted(String ipv6) { if (isValidIPv6(ipv6)) { ipv6 = ipv6.substring(0, ipv6.length() - 1); } return ipv6.replaceFirst("(^|:)(0+(:|$)){2,8}", "::"); } /** * ipv4或ipv6字符串 * * @return 4 :ipv4, 6:ipv6, 0:地址不对 * @throws Exception */ public static int isIpV4OrV6(String ipAdress) throws Exception { InetAddress address = InetAddress.getByName(ipAdress); if (address instanceof Inet4Address) return 4; else if (address instanceof Inet6Address) return 6; return 0; } /** * IPv4转换为IPv6 */ public static String ipv4ToIpv6(String ipv6) { String[] octets = ipv6.split("\\."); byte[] octetBytes = new byte[4]; for (int i = 0; i < 4; ++i) { octetBytes[i] = (byte) Integer.parseInt(octets[i]); } byte ipv4asIpV6addr[] = new byte[16]; ipv4asIpV6addr[10] = (byte) 0xff; ipv4asIpV6addr[11] = (byte) 0xff; ipv4asIpV6addr[12] = octetBytes[0]; ipv4asIpV6addr[13] = octetBytes[1]; ipv4asIpV6addr[14] = octetBytes[2]; ipv4asIpV6addr[15] = octetBytes[3]; return "::" + (ipv4asIpV6addr[12] & 0xff) + "." + (ipv4asIpV6addr[13] & 0xff) + "." + (ipv4asIpV6addr[14] & 0xff) + "." + (ipv4asIpV6addr[15] & 0xff); } /** * 判断ipv6是否合法 * * @param ip * @return */ public static boolean isValidIPv6(String ip) { if (ip == null || ip.trim().length() == 0) { return false; } String t = "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"; Pattern p = Pattern.compile(t); Matcher macher = p.matcher(ip); return macher.matches(); } /** * 判断IPv6是否属于某个IPv6段 * * @throws Exception */ public static boolean isBelongIpv6List(String ipv6, List<String> ipv6area) throws Exception { for (String iparea : ipv6area) { if (isBelongIpv6(ipv6, iparea)) { return true; } } return false; } /** * 判断ip是否属于某个网段 * * @param ip * @return */ public static boolean isBelongIpareaData(BigInteger ipv6, List<BigInteger[]> data) { for (BigInteger[] tmp : data) { if ((ipv6.compareTo(tmp[0]) == 1 || ipv6.compareTo(tmp[0]) == 0) && (ipv6.compareTo(tmp[1]) == -1 || ipv6.compareTo(tmp[1]) == 0)) { return true; } } return false; } public static BigInteger[] getIpv6Long(String iparea) { try { iparea = iparea.trim(); BigInteger[] info = new BigInteger[2]; // 判断是否是具体IP int index = iparea.indexOf("/"); if (index < 0) { info[0] = ipv6ToBytesToBigInteger(iparea); info[1] = ipv6ToBytesToBigInteger(iparea); if (info[0] == null || info[1] == null) { return null; } return info; } String ipinfo = iparea.substring(0, index); Integer count = Integer.valueOf(iparea.substring(index + 1)); BigInteger small = BigInteger.ZERO; BigInteger big = BigInteger.ZERO; StringBuffer mask = new StringBuffer(); for (int i = 0; i < 128; i++) { if (i<count) { mask.append("1"); }else { mask.append("0"); } } String string = new BigInteger(mask.toString(),2).toString(10); // for (int i = 0; i < 128 - count; i++) { // double pow = Math.pow(2d, Double.valueOf(Integer.valueOf(i).toString())); // BigInteger tmp = BigDecimal.valueOf(pow).toBigInteger(); // small = small.add(tmp); // } // big = BigDecimal.valueOf(Math.pow(2d, Double.valueOf("128"))).toBigInteger().subtract(small) // .subtract(BigInteger.valueOf(1)); //// //// info[0] = areaIp.and(big); //// info[1] = areaIp.or(small); BigInteger areaIp = ipv6ToBytesToBigInteger(ipinfo); info[0] = areaIp.and(new BigInteger(string)); String re = mask.substring(mask.lastIndexOf("1")+1).replace("0", "1"); info[1] = areaIp.or(new BigInteger(new BigInteger(re.toString(),2).toString(10)).subtract(BigInteger.valueOf(1))); if (info[0] == null || info[1] == null) { return null; } return info; } catch (Exception e) { return null; } } /** * 给定两个初始ip和结束ip,,计算求得CIDR IP段 * * @param startIp * @param endIp * @return */ public static List<String> range2cidrlist(String startIp, String endIp) { long start = ipToLong(startIp); long end = ipToLong(endIp); ArrayList<String> pairs = new ArrayList<String>(); while (end >= start) { byte maxsize = 32; while (maxsize > 0) { long mask = CIDR2MASK[maxsize - 1]; long maskedBase = start & mask; if (maskedBase != start) { break; } maxsize--; } double x = Math.log(end - start + 1) / Math.log(2); byte maxdiff = (byte) (32 - Math.floor(x)); if (maxsize < maxdiff) { maxsize = maxdiff; } String ip = Utilities.longToIP(start); pairs.add(ip + "/" + maxsize); start += Math.pow(2, (32 - maxsize)); } return pairs; } public static final int[] CIDR2MASK = new int[] { 0x00000000, 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF }; private static long ipToLong(String strIP) { long[] ip = new long[4]; String[] ipSec = strIP.split("\\."); for (int k = 0; k < 4; k++) { ip[k] = Long.valueOf(ipSec[k]); } return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; } }
原文地址:https://www.cnblogs.com/haojb/p/10343025.html
时间: 2024-10-22 09:31:17