/**
* Copyright (c) 2016-2019 ants All rights reserved.
*
*
* 版权所有,侵权必究!
*/
package io.ants.common.utils;
import com.alibaba.druid.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.jsonwebtoken.lang.Strings;
import org.apache.commons.net.util.SubnetUtils;
/**
* IP地址
*
* @author Mark sunlightcs@gmail.com
*/
public class IPUtils {
//private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = null;
try {
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
//logger.error("IPUtils ERROR ", e);
}
// //使用代理,则获取第一个IP地址
// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
// if(ip.indexOf(",") > 0) {
// ip = ip.substring(0, ip.indexOf(","));
// }
// }
//使用代理,则获取第一个IP地址
if(!StringUtils.isEmpty(ip) && ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
return ip;
}
private static final String IPV4_REGEX = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";
private static final Pattern IPV4_PATTERN = Pattern.compile(IPV4_REGEX);
public static boolean isValidIPV4ByCustomRegex(String ip) {
if (ip == null || ip.trim().isEmpty()) {
return false;
}
if (!IPV4_PATTERN.matcher(ip).matches()) {
return false;
}
String[] parts = ip.split("\\.");
try {
for (String segment : parts) {
boolean testStatus=Integer.parseInt(segment) > 255 || (segment.length() > 1 && segment.startsWith("0"));
if (testStatus) {
return false;
}
}
} catch (NumberFormatException e) {
return false;
}
return true;
}
public static boolean isValidIPV6(String ip){
if (null==ip){
return false;
}
String pattern = "^\\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}:)(((:[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 r = Pattern.compile(pattern);
Matcher m = r.matcher(ip);
return m.matches();
}
public static boolean isValidIPV4(String ip){
if (null==ip || "".equals(ip) ){
return false;
}
String pattern = "((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(ip);
return m.matches();
}
public static boolean isValidIpv4OrIpv6(String ip){
return isValidIPV4(ip) || isValidIPV6(ip);
}
public static boolean isValidPort(String port){
if (null==port || "".equals(port) ){
return false;
}
String pattern = "^([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(port);
return m.matches();
}
//核心代码,检索IP所属网段
public static boolean isInRange(String ip, String cidr) {
String[] ips = ip.split("\\.");
long ipAddr = (Long.parseLong(ips[0]) << 24)
| (Long.parseLong(ips[1]) << 16)
| (Long.parseLong(ips[2]) << 8)
| Long.parseLong(ips[3]);
long type = Long.parseLong(cidr.replaceAll(".*/", ""));
long mask = 0xFFFFFFFF << (32 - type);
String cidrIp = cidr.replaceAll("/.*", "");
String[] cidrIps = cidrIp.split("\\.");
long networkIpAddr = (Long.parseLong(cidrIps[0]) << 24)
| (Long.parseLong(cidrIps[1]) << 16)
| (Long.parseLong(cidrIps[2]) << 8)
| Long.parseLong(cidrIps[3]);
return (ipAddr & mask) == (networkIpAddr & mask);
}
public static boolean isCidr(String ip){
if (null==ip || "".equals(ip) ){
return false;
}
final String pattern = "^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\/([1-9]|[1-2]\\d|3[0-2])$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(ip);
if(m.matches()){
return true;
}
return false;
}
public static String normalizeFromCIDR(final String netspec) {
final int bits = 32 - Integer.parseInt(netspec.substring(netspec.indexOf('/') + 1));
final int mask = (bits == 32) ? 0 : 0xFFFFFFFF - ((1 << bits) - 1);
return netspec.substring(0, netspec.indexOf('/') + 1) + Integer.toString(mask >> 24 & 0xFF, 10) + "." + Integer.toString(mask >> 16 & 0xFF, 10) + "." + Integer.toString(mask >> 8 & 0xFF, 10) + "." + Integer.toString(mask >> 0 & 0xFF, 10);
}
private static long bytesToLong(byte[] address) {
long ipnum = 0;
for (int i = 0; i < 4; ++i) {
long y = address[i];
if (y < 0) {
y += 256;
}
ipnum += y << ((3 - i) * 8);
}
return ipnum;
}
public static String long2ip(long l) {
String s = "";
for (int i1 = 0; i1 < 4; i1++) {
if (i1 > 0) {
s = s + ".";
}
int k = (int) ((l / Math.pow(2D, (3 - i1) * 8)) % 256D);
s = s + "" + k;
}
return s;
}
public static long ip2long(String ip) {
long result = 0;
if (Strings.hasLength(ip)) {
String[] section = ip.split("\\.");
if (section.length > 2) {
for (int i = 0; i < section.length; i++) {
result += Long.parseLong(section[i]) << ((section.length - i - 1) * 8);
}
}
}
return result;
}
public static long[] getLowerAndUpper( String subnet){
try{
if (isCidr(subnet)){
SubnetUtils utils = new SubnetUtils(subnet);
Inet4Address a = (Inet4Address) InetAddress.getByName(utils.getInfo().getHighAddress());
long high = bytesToLong(a.getAddress())+1;
Inet4Address b = (Inet4Address) InetAddress.getByName(utils.getInfo().getLowAddress());
long low = bytesToLong(b.getAddress())-1;
//System.out.println(low);
//System.out.println(long2ip(low));
//System.out.println(high);
//System.out.println(long2ip(high));
return new long[] { low, high };
}else if(isValidIPV4(subnet)){
long value=ip2long(subnet);
return new long[] { value, value };
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
//System.out.println(normalizeFromCIDR("192.168.1.1/16"));
System.out.println(getLowerAndUpper("192.168.1.1/16")[0]);
}
}