package com.bingo.helloworld.Util;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
/**
* 使用方法前请验证IP是否正确
*
* @author Mr. y
*
*/
public class IPUtil {
/**
* 判断IP类型 支持IPv4和IPv6
*
* @param ip
* @return
*/
public static int ipType(String ip) {
if (ip.indexOf(".") > 0 && ip.split("\\.").length == 4) {
return 4;
}
if (ip.indexOf(":") > 0) {
return 6;
}
return -1;
}
/**
* 获取十六进制格式的IP
*
* @param ip
* @return
*/
public static String ipToHexIp(String ip) {
if (ipType(ip) == 4) {
return String.format("4-%08X", ipToLong(ip));
}
if (ipType(ip) == 6) {
return String.format("6-%032X", ipv6ToBigInteger(ip));
}
return ip;
}
/**
* 由十六进制格式的IP转为正常IP格式
*
* @param ip
* @return
*/
public static String hexIpToIp(String ip) {
int len = ip.length();
if (ip.indexOf('-') == 1) {
if (ip.charAt(0) == '4' && len == 10) {
return longToIp(Long.parseLong(ip.substring(2), 16));
} else if (ip.charAt(0) == '6' && len == 34) {
return BigIntegerToIpv6(new BigInteger(ip.substring(2), 16));
} else {
return ip;
}
}
return ip;
}
/**
* 输入起始IP和结束IP,将其间的所有IP都放入到List中
*
* @param stip
* 起始IP
* @param etip
* 结束IP
* @return 存放IP的集合
* @throws Exception
*/
public static List<String> ipRangeToList(String ipStart, String ipEnd) {
List<String> ipList = new ArrayList<String>();
if (ipType(ipStart) == 4 && ipType(ipEnd) == 4) {
long start = ipToLong(ipStart);
long end = ipToLong(ipEnd);
for (long i = start; i <= end; i++) {
ipList.add(longToIp(i));
}
} else if (ipType(ipStart) == 6 && ipType(ipEnd) == 6) {
BigInteger start = ipv6ToBigInteger(ipStart);
BigInteger end = ipv6ToBigInteger(ipEnd);
for (BigInteger i = start; i.compareTo(end) < 0; i = i
.add(new BigInteger("1"))) {
ipList.add(BigIntegerToIpv6(i));
}
}
return ipList;
}
/**
* IP段非重复部分的检测 比如数据库中已有IP段 10.10.10.2-10.10.10.10,10.10.10.30-10.10.10.50
* 再插入一个IP段 比如:10.10.10.7-10.10.10.65,但是不能和数据库中的IP段重复
* 最终插入结果是:10.10.10.11-10.10.10.29和10.10.10.51-10.10.10.65被插入到数据库
*
* @param ipLists
* 已有IP段
* @param startIps
* 插入的起始IP
* @param endIps
* 插入的结束IP
* @author Mr. y
* @return
*/
public static ArrayList<String[]> getElseIpRangeList(
ArrayList<String[]> ipLists, String startIp, String endIp) {
// 排序,使list中数组从小到大
Collections.sort(ipLists, new Comparator<String[]>() {
public int compare(String[] arg0, String[] arg1) {
return ipToHexIp(arg0[0]).compareTo(ipToHexIp(arg0[1]));
}
});
ArrayList<String[]> list = new ArrayList<String[]>();
int num = 1;
for (String[] ips : ipLists) {
String sIp = ips[0];
String eIp = ips[1];
if (startIp.compareTo(sIp) < 0) {
if (endIp.compareTo(sIp) < 0) {
list.add(new String[] { new String(startIp),
new String(endIp) });
break;
}
if (endIp.compareTo(sIp) >= 0 && endIp.compareTo(eIp) <= 0) {
list.add(new String[] { new String(startIp),
new String(lastIp(sIp)) });
break;
}
if (endIp.compareTo(eIp) > 0) {
list.add(new String[] { new String(startIp),
new String(lastIp(sIp)) });
if (num != ipLists.size()) {
startIp = nextIp(eIp);
num++;
continue;
} else {
list.add(new String[] { new String(nextIp(eIp)),
new String(endIp) });
break;
}
}
}
if (startIp.compareTo(sIp) >= 0 && startIp.compareTo(eIp) <= 0) {
if (endIp.compareTo(eIp) <= 0) {
break;
}
if (endIp.compareTo(eIp) > 0) {
if (num != ipLists.size()) {
startIp = nextIp(eIp);
num++;
continue;
} else {
list.add(new String[] { new String(nextIp(eIp)),
new String(endIp) });
break;
}
}
}
if (startIp.compareTo(eIp) > 0) {
if (num != ipLists.size()) {
num++;
continue;
} else {
list.add(new String[] { new String(startIp),
new String(endIp) });
break;
}
}
}
return list;
}
/**
* 所传入IP的下一个IP
*
* @param ip
* 支持IPv4和IPv6
* @author Mr. y
* @return
*/
public static String nextIp(String ip) {
String nextIp = "";
if (ipType(ip) == 4) {
nextIp = longToIp(ipToLong(ip) + 1);
}
if (ipType(ip) == 6) {
nextIp = BigIntegerToIpv6(ipv6ToBigInteger(ip).add(
new BigInteger("1")));
}
return nextIp;
}
/**
* 所传入IP的上一个IP
*
* @param ip
* 支持IPv4和IPv6
* @author Mr. y
* @return
*/
public static String lastIp(String ip) {
String lastIp = "";
if (ipType(ip) == 4) {
lastIp = longToIp(ipToLong(ip) - 1);
}
if (ipType(ip) == 6) {
lastIp = BigIntegerToIpv6(ipv6ToBigInteger(ip).subtract(
new BigInteger("1")));
}
return lastIp;
}
/**
* ipv4转换为long类型
*
* @param ipv4
* IP范围:0.0.0.0-255.255.255.255
* @author Mr. y
* @return
*/
public static long ipToLong(String ipv4) {
String[] ips = ipv4.split("\\.");
int d1 = Integer.parseInt(ips[0]);
int d2 = Integer.parseInt(ips[1]);
int d3 = Integer.parseInt(ips[2]);
int d4 = Integer.parseInt(ips[3]);
long l = 0x1000000L * d1 + 0x10000 * d2 + 0x100 * d3 + d4;
return l;
}
/**
* long类型转换为ipv4
*
* @param l
* 0-4294967295
* @author Mr. y
* @return
*/
public static String longToIp(long l) {
String ip = "";
ip += (l >>> 24);
ip += "." + ((0x00ffffff & l) >>> 16);
ip += "." + ((0x0000ffff & l) >>> 8);
ip += "." + (0x000000ff & l);
return ip;
}
/**
* ipv6转换为BigInteger类型
*
* @param ipv6
* IP范围:0000:0000:0000:0000:0000:0000:0000:0000 -
* FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
* @author Mr. y
* @return
*/
public static BigInteger ipv6ToBigInteger(String ipv6) {
int compressIndex = ipv6.indexOf("::");
if (compressIndex != -1) {
String part1s = ipv6.substring(0, compressIndex);
String part2s = ipv6.substring(compressIndex + 1);
BigInteger part1 = ipv6ToBigInteger(part1s);
BigInteger part2 = ipv6ToBigInteger(part2s);
int part1hasDot = 0;
char ch[] = part1s.toCharArray();
for (char c : ch) {
if (c == ':') {
part1hasDot++;
}
}
return part1.shiftLeft(16 * (7 - part1hasDot)).add(part2);
}
String[] str = ipv6.split(":");
BigInteger bigInt = BigInteger.ZERO;
for (int i = 0; i < str.length; i++) {
// ::1
if (str[i].isEmpty()) {
str[i] = "0";
}
bigInt = bigInt.add(BigInteger.valueOf(Long.valueOf(str[i], 16))
.shiftLeft(16 * (str.length - i - 1)));
}
return bigInt;
}
/**
* BigInteger类型转换为ipv6
*
* @param big
* 0-340282366920938463463374607431768211455
* @author Mr. y
* @return
*/
public static String BigIntegerToIpv6(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}", "::");
}
/**
* 验证Ipv4是否正确 0.0.0.0 - 255.255.255.255
*
* @param Ipv4
* @author Mr. y
* @return
*/
public static boolean validateIpv4(String Ipv4) {
String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
Pattern pattern = Pattern.compile(regex);
return pattern.matcher(Ipv4).matches();
}
/**
* 验证Ipv6是否正确 ::1-FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
*
* @param Ipv6
* @author Mr. y
* @return
*/
public static boolean validateIpv6(String Ipv6) {
StringBuffer regex = new StringBuffer();
regex.append(
"^([\\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|")
.append("^::([\\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|")
.append("^([\\da-fA-F]{1,4}:):([\\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|")
.append("^([\\da-fA-F]{1,4}:){2}:([\\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|")
.append("^([\\da-fA-F]{1,4}:){3}:([\\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|")
.append("^([\\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$|")
.append("^([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}$|")
.append("^:((:[\\da-fA-F]{1,4}){1,6}|:)$|")
.append("^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)$|")
.append("^([\\da-fA-F]{1,4}:){2}((:[\\da-fA-F]{1,4}){1,4}|:)$|")
.append("^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)$|")
.append("^([\\da-fA-F]{1,4}:){4}((:[\\da-fA-F]{1,4}){1,2}|:)$|")
.append("^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?$|")
.append("^([\\da-fA-F]{1,4}:){6}:$");
Pattern pattern = Pattern.compile(regex.toString());
return pattern.matcher(Ipv6).matches();
}
}