package com.nis.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.nis.domain.Nets; import javax.servlet.http.HttpServletRequest; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * *
对IPV4进行处理工具类.
* @author 中电积至有限公司 darnell * @version 1.0 创建时间:2018-08-30 * */ public class IPUtil { private static Logger logger = LoggerFactory.getLogger(IPUtil.class); private static byte pos []= new byte []{(byte)128,64,32,16,8,4,2,1}; private static final Pattern IPV4Pattern = Pattern. compile("\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b"); private static final Pattern IPV6_STD_PATTERN = Pattern.compile( "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$"); private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile( "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$"); /** * *将10进制IP转为字符串,网络序。IP((0-255).(0-255).(0-255).(0-255))格式. * ip10为字符串形式能给处理带来方便. *
*
* IpUtil.getIpString("3232235777") = "192.168.1.1"
*
* @see #getIpDesimal(String)
* @param ip10 10进制IP
* @return 返回如0.0.0.0格式IP
*/
public static String getIpString(String ip10) {
StringBuffer sb = new StringBuffer("");
if (ip10.indexOf("-") > -1) {
Integer intIP = Integer.parseInt(setStrEmpty(ip10));
sb.append(String.valueOf(intIP&0x000000FF));
sb.append(".");
sb.append(String.valueOf((intIP&0x0000FFFF)>>>8));
sb.append(".");//将高8位置0,然后右移16位
sb.append(String.valueOf((intIP&0x00FFFFFF)>>>16));
sb.append(".");
sb.append(String.valueOf(intIP>>>24&0xFF));//直接右移24位
return sb.toString();
} else {
Long longIP = Long.parseLong(setStrEmpty(ip10));
sb.append(String.valueOf(longIP&0x000000FF));
sb.append(".");
sb.append(String.valueOf((longIP&0x0000FFFF)>>>8));
sb.append(".");//将高8位置0,然后右移16位
sb.append(String.valueOf((longIP&0x00FFFFFF)>>>16));
sb.append(".");
sb.append(String.valueOf(longIP>>>24&0xFF));//直接右移24位
return sb.toString();
}
}
/**
*
* 将10进制IP转为字符串,主机序。IP((0-255).(0-255).(0-255).(0-255))格式. * ip10为字符串形式能给处理带来方便. *
*
* IpUtil.getIpHostString("3232235777") = "192.168.1.1"
*
* @see #getIpDesimal(String)
* @param ip10 10进制IP
* @return 返回如0.0.0.0格式IP
*/
//将10进制整数形式转换成127.0.0.1形式的IP地址,按网络序
public static String getIpHostString(String ip10) {
StringBuffer sb = new StringBuffer(32);
if (ip10.indexOf("-") > -1) {
Integer intIP = Integer.parseInt(setStrEmpty(ip10));
sb.append(String.valueOf(intIP >>> 24));// 直接右移24位
sb.append(".");
sb.append(String.valueOf((intIP & 0x00FFFFFF) >>> 16)); // 将高8位置0,然后右移16位
sb.append(".");
sb.append(String.valueOf((intIP & 0x0000FFFF) >>> 8));
sb.append(".");
sb.append(String.valueOf(intIP & 0x000000FF));
return sb.toString();
} else {
Long longIP = Long.parseLong(setStrEmpty(ip10));
sb.append(String.valueOf(longIP >>> 24));// 直接右移24位
sb.append(".");
sb.append(String.valueOf((longIP & 0x00FFFFFF) >>> 16)); // 将高8位置0,然后右移16位
sb.append(".");
sb.append(String.valueOf((longIP & 0x0000FFFF) >>> 8));
sb.append(".");
sb.append(String.valueOf(longIP & 0x000000FF));
return sb.toString();
}
}
/**
* 判断一个IP地址是否属于某一个子网
*
* @param ip IP地址
* @param prefix 子网地址
* @param prefixLen 掩码长度
* @return true or false
*/
public static boolean inPrefix(String ip, String prefix, int prefixLen) {
String binPrefix = toBinaryString(prefix);
if (binPrefix.length() > prefixLen) {
binPrefix = binPrefix.substring(0,prefixLen);
}
String binIP = toBinaryString(ip);
binIP = binIP.substring(0,prefixLen);
if (binIP.equals(binPrefix)) {
return true;
} else {
return false;
}
}
/**
* 获得两个IP间的范围,如192.168.0.128-192.168.2.256。
* 注意:本方法不做合法性检查!
*
* @param startIp 起始IP
* @param endIp 中止IP
* @return 范围内的IP地址数组
*/
public static List根据标准ip段获取,该段子网掩码 *
* @param startIP 起始ip,endIP 结束ip * @return 返回如子网掩码格式IP
*/
public static String getMask(String startIP,String endIP) {
byte start [] = getAddress(startIP);
byte end [] = getAddress(endIP);
byte mask [] = new byte [start.length];
boolean flag=false;
for(int i=0; i将整型的掩码转换成IPv4型(30 -> 255.255.255.252).
* * @param mask 整型掩码. * @return IPv4型掩码. * @exception RuntimeException 掩码错误. */ public static String convertMask(int mask) { if (mask > 32 || mask < 8) { throw(new RuntimeException("掩码错误!应为8-32的整数。")); } return toIPString(maskToBinaryString(mask)); } /** *将整型的掩码转换成反向IPv4型(30 -> 255.255.255.252).
* * @param mask 整型掩码. * @return IPv4型反向掩码. * @exception Exception 掩码错误. */ public static String convertReverseMask(int mask) throws Exception { if (mask > 32 || mask < 8) { throw(new Exception("掩码错误!应为8-32的整数。")); } return toIPString(reverseMaskToBinaryString(mask)); } /** * 将整型掩码转换成二进制字符串 * @param mask 整型掩码 * @return 二进制型掩码. */ private static String maskToBinaryString(int mask) { StringBuffer str = new StringBuffer(); for(int i=1;i<=32;i++) { if (i <= mask) { str.append('1'); } else { str.append('0'); } } return str.toString(); } /** * 将整型掩码转换成二进制字符串 * @param mask 整型掩码 * @return 反向二进制型掩码. */ private static String reverseMaskToBinaryString(int mask) { StringBuffer str = new StringBuffer(); for(int i=1;i<=32;i++) { if (i <= mask) { str.append('0'); } else { str.append('1'); } } return str.toString(); } /** * 将二进制字符串转换成IPv4型字符串 * @param binary 二进制字符串 * @return IPv4型IP. */ private static String toIPString(String binary) { if (binary.length() < 32) { for (int i=binary.length();i<32;i++) { binary = "0" + binary; } } String part1 = binary.substring(0,8); String part2 = binary.substring(8,16); String part3 = binary.substring(16,24); String part4 = binary.substring(24); return Integer.parseInt(part1,2) + "." + Integer.parseInt(part2,2) + "." + Integer.parseInt(part3,2) + "." + Integer.parseInt(part4,2); } /** * 获取子网的网络地址. * * @param ip IP地址. * @param mask 掩码. * @return 网络地址. * @exception Exception IP地址错误或掩码错误. */ public static String getSubNetIP(String ip, int mask) throws Exception { if (!isIP(ip)) { throw(new Exception("IP地址不合法!")); } String s1 = toBinaryString(ip); String s2 = maskToBinaryString(mask); return toIPString(Long.toBinaryString(Long.parseLong(s1,2)&Long.parseLong(s2,2))); } /** *将整型掩码转换成IPv4型的反码(30 -> 0.0.0.3).
* * @param mask 整型掩码. * @return IPv4型反码. * @exception Exception 掩码错误. */ public static String reverseMask(int mask) throws Exception { if (mask > 32 || mask < 8) { throw(new Exception("掩码错误!应为8-32的整数。")); } String str = maskToBinaryString(mask); str = str.replace('0','2'); str = str.replace('1','0'); str = str.replace('2','1'); return toIPString(str); } /** * 将IPv4型字符串转换成长度为32的二进制字符串 * 需要加验证是否为IP */ public static String toBinaryString(String ip) { String[] array = ip.split("[.]"); String str = ""; for (int i=0; i例子说明:* @param ip ip字符 * @return
true ip符合验证规则, false ip不符合验证规则.
*/
public static boolean isIP(String ip) {
if (ip == null) {
return false;
}
Matcher mat = IPV4Pattern.matcher(ip);
return mat.matches();
}
public static boolean isIPv6StdAddress(final String input) {
return IPV6_STD_PATTERN.matcher(input).matches();
}
public static boolean isIPv6HexCompressedAddress(final String input) {
return IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches();
}
public static boolean isIPv6Address(final String input) {
return isIPv6StdAddress(input) || isIPv6HexCompressedAddress(input);
}
/**
*
* 在web方式下获取客户端IP地址.
** 使用该方法,需要在有javaee.jar扩展包前提下. *
* @param request HttpServletRequest请求对象 * @return 返回字符串IP地址 */ public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } /** * *验证mask是否符合规则.给定字符串,判断是否符合正则验证的mask格式.
*例子说明:* @param mask mask字符 * @return
true mask符合验证规则, false mask不符合验证规则.
*/
public static boolean isMask(String mask) {
if (mask == null) {
return false;
}
if(!isIP(mask)){
return false;
}
String[] ips = mask.split("\\.");
String binaryVal = "";
for (int i = 0; i < ips.length; i++)
{
String binaryStr = Integer.toBinaryString(Integer.parseInt(ips[i]));
Integer times = 8 - binaryStr.length();
for(int j = 0; j < times; j++)
{
binaryStr = "0" + binaryStr;
}
binaryVal += binaryStr;
}
if(binaryVal.indexOf("01")!=-1){
return false;
}
return true;
}
/**
*
* 将IP进制转换成十进制网络字节序
** IP是一个字符串,符合IP的规则(0-255).(0-255).(0-255).(0-255). * 将ip转换成长整型的原因是:处理时间类型简单;入库节省空间,查询提高效率. *
*
* IpUtil.getIpDesimal("192.168.1.1") = 3232235777
* IpUtil.getIpDesimal("192.168.1.256") = -1 //不符合Ip规则
*
* @see #getIpString(String)
* @param ip 符合IP规则的字符串
* @return -1 验证ip不合法,ip 计算ip返回长整型.
*/
public static long getIpDesimal(String ip) {
long ip10 = 0;
if (!isIP(ip)) {
return -1; // ip 不合法
}
String[] ss = ip.trim().split("\\.");
for (int i = 0; i < 4; i++) {
ip10 += Math.pow(256, i) * Long.parseLong(ss[i]);
}
return ip10;
}
/**
*
* 将IP进制转换成十进制主机字节序
** IP是一个字符串,符合IP的规则(0-255).(0-255).(0-255).(0-255). * 将ip转换成长整型的原因是:处理时间类型简单;入库节省空间,查询提高效率. *
*
* IpUtil.getIpHostDesimal("192.168.1.1") = 3232235777
* IpUtil.getIpHostDesimal("192.168.1.256") = -1 //不符合Ip规则
*
* @see #getIpString(String)
* @param ip 符合IP规则的字符串
* @return -1 验证ip不合法,ip 计算ip返回长整型.
*/
public static long getIpHostDesimal(String ip) {
long ip10 = 0;
if (!isIP(ip)) {
return -1; // ip 不合法
}
String[] ss = ip.trim().split("\\.");
for (int i = 0; i < 4; i++) {
ip10 += Math.pow(256, 3 - i) * Long.parseLong(ss[i]);
}
return ip10;
}
/**
*
* 获取IP/mask 包含IP数量,适合完整IPw网段
** * *
*
*
*
*
* @param ip 符合IP规则的字符串
* @param mask 掩码格式
* @return -1 验证ip不合法,ip 计算ip返回长整型.
*/
public static long getIpNum(String ip, int mask) {
long num = 0;
if (isIP(ip)) {
String endIp = getEndIP(ip, mask);
num = getIpHostDesimal(endIp) - getIpHostDesimal(ip) +1;
} else {
throw new IllegalArgumentException("所传入的IP地址不符合IPV4规范");
}
return num;
}
// 此方法用于判断数据为空就置为0
private static String setStrEmpty(String str) {
if ("".equals(str) || str == null) {
str = "0";
}
return str;
}
private static String toString(byte[] address) {
StringWriter sw = new StringWriter(16);
sw.write(Integer.toString(address[0]&0xFF));
for(int i=1;i