public class IPSubnetUtil {
public static final String IPADDRESS_REGEX = "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))";
public static final String SUBNET_MASK_REGEX1 = "[/](255)[.](255)[.](255)[.]((0)|(128)|(192)|(224)|(240)|(248)|(252)|(254)|(255))";
public static final String SUBNET_MASK_REGEX2 = "[/]((2[4-9])|(3[0-2]))";
private static boolean inclusiveHostCount = false;
/**
* 避免被实例化
*/
private IPSubnetUtil() {
}
/**
* 通过IP/子网掩码得到IP地址列表, 仅支持C类IP(如 10.19.245.64/26 或 10.19.245.64/255.255.255.192)
*/
public static List<String> getWhiteIPBySubnetMask(String whiteIP) {
List<String> addressesList = new ArrayList<String>();
if (whiteIP.matches(IPADDRESS_REGEX + SUBNET_MASK_REGEX1)
|| whiteIP.matches(IPADDRESS_REGEX + SUBNET_MASK_REGEX2)) {
String[] parts = whiteIP.split("/");
long address = convertString2Ipaddr(parts[0]);
long netmask = convertString2Mask(parts[1]);
long network = getNetwork(address, netmask);
long brodcast = getBrodcast(network, netmask);
setIsInclusiveHostCount(parts[1]);
for (long add = getLow(address, netmask, network); add <= getHigh(address, network, netmask, brodcast); ++add) {
addressesList.add(format(toArray(add)));
}
return addressesList;
} else {
return addressesList;
}
}
public static boolean validateIPFormat(String ip) {
return ip.matches(IPADDRESS_REGEX) ? true : false;
}
/**
* 得到第一个可用地址
*/
private static long getLow(long address, long netmask, long network) {
return (isInclusiveHostCount() ? getNetwork(address, netmask) : getBrodcast(network, netmask)
- getNetwork(address, netmask) > 1 ? getNetwork(address, netmask) + 1 : 0);
}
/**
* 得到网络地址
*/
private static long getNetwork(long address, long netmask) {
return (address & netmask);
}
/**
* 得到最后一个可用地址
*/
private static long getHigh(long address, long network, long netmask, long brodcast) {
return (isInclusiveHostCount() ? getBrodcast(network, netmask) : getBrodcast(network, netmask)
- getNetwork(address, netmask) > 1 ? getBrodcast(network, netmask) - 1 : 0);
}
/**
* 得到广播地址
*/
private static long getBrodcast(long network, long netmask) {
return (network | ~(netmask)) & 0xffffffffl;
}
private static boolean isInclusiveHostCount() {
return inclusiveHostCount;
}
/**
* 若所给IP段有网络地址和广播地址, 则返回true
*/
private static void setIsInclusiveHostCount(String netmask) {
inclusiveHostCount = netmask.equals("32") || netmask.equals("31") || netmask.equals("255.255.255.255")
|| netmask.equals("255.255.255.254") ? true : false;
}
/**
* 将int数组转换为IP地址
*/
private static String format(int[] octets) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < octets.length; ++i) {
str.append(octets[i]);
if (i != octets.length - 1) {
str.append(".");
}
}
return str.toString();
}
/**
* 将ip地址转换为int数组
*/
private static int[] toArray(long val) {
int ret[] = new int[4];
for (int j = 3; j >= 0; --j) {
ret[j] |= ((val >>> 8 * (3 - j)) & (0xff));
}
return ret;
}
/**
* 得到子网掩码
*/
private static long convertString2Mask(String mask) {
return (mask.contains(".") ? convertString2Ipaddr(mask) : convertNum2Mask(mask));
}
/**
* 将数字转换为子网掩码
*/
private static long convertNum2Mask(String mask) {
return (0xffffffffl << (32 - Integer.parseInt(mask))) & 0xffffffffl;
}
/**
* IP地址转为整数型
*/
private static long convertString2Ipaddr(String ip) {
long ipv4 = 0x00;
String[] ipArr = ip.split("\\.");
for (int i = 0; i < ipArr.length; i++) {
long seg = Long.parseLong(ipArr[i]);
ipv4 = (ipv4 << 8) | seg;
}
return ipv4;
}
}
参考了commons-net-3.1-bin.jar中的SubnetUtil.java类写成
返回的IP用List<String>保存
未加入去重功能
请大家指教~