package com.cjh.ip.utils;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* @author cjh
* 2014年7月28日 上午10:38:39
*/
public class IPUtil {
/**
* 计算IP地址段,并返回Map:{"startIp": startIp,"endIp": endIp}
* @param ip
* @param mask
* @return Map:{"startIp": startIp,"endIp": endIp}
*/
public static Map<String, Object> parseToNetSegmentMap(String ip,int mask){
long start = ipToLong(ip); // 地址
long number = ipCount(mask); // ip地址个数
long lmask = maskToLong(mask); // 掩码
Map<String, Object> map = new HashMap<String, Object>();
map.put("startIp", longToIP(start & lmask));
map.put("endIp", longToIP((start & lmask) + number));
return map;
}
/**
* 计算IP地址段,并返回:"起始ip--结束ip"形式字符串。
* @param ip
* @param mask
* @return String "起始ip--结束ip"
*/
public static String parseToNetSegmentString(String ip,int mask){
long start = ipToLong(ip); // 地址
long number = ipCount(mask); // ip地址个数
long lmask = maskToLong(mask); // 掩码
return (longToIP(start & lmask))+"--"+(longToIP((start & lmask) + number));
}
/**
* 计算出掩码指定的IP地址个数 如: 24
*
* @param mask
* @return long
*/
public static long ipCount(int mask) {
long number = 0;
for (int i = 0; i < 32 - mask; i++) {
number += Math.pow(2, i);
}
return number;
}
/**
* 分割IP地址,对该地址是否为IP地址做了简单判断。
* @param ip
* @return
*/
public static long[] splitIp(String ip) {
long[] ipArray = new long[4];
int position1 = ip.indexOf(".");
int length = ip.length();
if (length >= 7 && length < 16) {
if (position1 > 0) {
int position2 = ip.indexOf(".", position1 + 1);
if (position2 > 0) {
int position3 = ip.indexOf(".", position2 + 1);
if (position3 > 0 && position3 < length - 1) {
try {
ipArray[0] = Long.parseLong(ip.substring(0, position1));
ipArray[1] = Long.parseLong(ip.substring(position1 + 1, position2));
ipArray[2] = Long.parseLong(ip.substring(position2 + 1, position3));
ipArray[3] = Long.parseLong(ip.substring(position3 + 1));
} catch (NumberFormatException e) {
return null;
}
} else {
return null;
}
} else {
return null;
}
} else {
return null;
}
} else {
return null;
}
return ipArray;
}
/**
* 将10.0.0.0形式的ip地址转换成10进制整数
*
* @param str
* @return long
* 若无法转换,则返回0
*/
public static long ipToLong(String str) {
long[] ip = splitIp(str);
if (ip != null) {
// ip=*256*256*256+ip2*256*256+ip3*256+ip4
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
} else {
return 0;
}
}
/**
* 将10.0.0.0形式的掩码地址转换成10进制整数
*
* @param mask
* @return
*/
public static long maskToLong(int mask) {
long longMask = 0;
for (int i = 31; i >= 32 - mask; i--) {
longMask += Math.pow(2, i);
}
return longMask;
}
/**
* 将10进制整数形式转换成127.0.0.1形式的IP地址
*
* @param longIp
* @return String
*/
public static String longToIP(long longIp) {
StringBuffer sb = new StringBuffer("");
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();
}
/**
* 判断是否为内网地址。
*
* @param ipAddress
* 需要判断的IP
* @return
*/
public static boolean isInnerIP(String ipAddress) {
if(!isIPAdress(ipAddress)){
return false;
}
boolean isInnerIp = false;
long ipNum = ipToLong(ipAddress);
/**
* 私有IP:
* A类 10.0.0.0-10.255.255.255
* B类 172.16.0.0-172.31.255.255
* C类 192.168.0.0-192.168.255.255
* D类 127.0.0.1
**/
long aBegin = ipToLong("10.0.0.0");
long aEnd = ipToLong("10.255.255.255");
long bBegin = ipToLong("172.16.0.0");
long bEnd = ipToLong("172.31.255.255");
long cBegin = ipToLong("192.168.0.0");
long cEnd = ipToLong("192.168.255.255");
isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || ipAddress.equals("127.0.0.1");
return isInnerIp;
}
/**
* 判断IP是否在某个IP地址区间
*
* @param userIp
* 待判断的IP
* @param begin
* 区间开始
* @param end
* 区间结束
* @return
*/
public static boolean isInner(long userIp, long begin, long end) {
return (userIp >= begin) && (userIp <= end);
}
/**
* 简单判断是否是IP地址
* @param str
* @return
*/
public static boolean isIPAdress(String str)
{
Pattern pattern = Pattern.compile( "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$" );
return pattern.matcher(str).matches();
}
}