/** * 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]); } }