1 package com.guodu.common.core.utils.ip; 2 3 import java.net.InetAddress; 4 import java.net.UnknownHostException; 5 import java.util.regex.Matcher; 6 import java.util.regex.Pattern; 7 import javax.servlet.http.HttpServletRequest; 8 9 import com.guodu.common.core.utils.StringUtils; 10 11 /** 12 * 获取IP方法 13 * 14 * @author guodu 15 */ 16 public class IpUtils { 17 public static String getIpAddr(HttpServletRequest request) { 18 String ip = null; 19 20 // X-Forwarded-For:Squid 服务代理 21 String ipAddresses = request.getHeader("X-Forwarded-For"); 22 if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { 23 // Proxy-Client-IP:apache 服务代理 24 ipAddresses = request.getHeader("Proxy-Client-IP"); 25 } 26 if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { 27 // WL-Proxy-Client-IP:weblogic 服务代理 28 ipAddresses = request.getHeader("WL-Proxy-Client-IP"); 29 } 30 if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { 31 // HTTP_CLIENT_IP:有些代理服务器 32 ipAddresses = request.getHeader("HTTP_CLIENT_IP"); 33 } 34 if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { 35 // X-Real-IP:nginx服务代理 36 ipAddresses = request.getHeader("X-Real-IP"); 37 } 38 39 // 有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP 40 if (ipAddresses != null && ipAddresses.length() != 0) { 41 ip = ipAddresses.split(",")[0]; 42 } 43 44 // 还是不能获取到,最后再通过request.getRemoteAddr();获取 45 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) { 46 ip = request.getRemoteAddr(); 47 } 48 return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip; 49 } 50 51 public static boolean internalIp(String ip) { 52 byte[] addr = textToNumericFormatV4(ip); 53 return internalIp(addr) || "127.0.0.1".equals(ip); 54 } 55 56 private static boolean internalIp(byte[] addr) { 57 if (StringUtils.isNull(addr) || addr.length < 2) { 58 return true; 59 } 60 final byte b0 = addr[0]; 61 final byte b1 = addr[1]; 62 // 10.x.x.x/8 63 final byte SECTION_1 = 0x0A; 64 // 172.16.x.x/12 65 final byte SECTION_2 = (byte) 0xAC; 66 final byte SECTION_3 = (byte) 0x10; 67 final byte SECTION_4 = (byte) 0x1F; 68 // 192.168.x.x/16 69 final byte SECTION_5 = (byte) 0xC0; 70 final byte SECTION_6 = (byte) 0xA8; 71 switch (b0) { 72 case SECTION_1: 73 return true; 74 case SECTION_2: 75 if (b1 >= SECTION_3 && b1 <= SECTION_4) { 76 return true; 77 } 78 case SECTION_5: 79 switch (b1) { 80 case SECTION_6: 81 return true; 82 } 83 default: 84 return false; 85 } 86 } 87 88 /** 89 * 将IPv4地址转换成字节 90 * 91 * @param text IPv4地址 92 * @return byte 字节 93 */ 94 public static byte[] textToNumericFormatV4(String text) { 95 if (text.length() == 0) { 96 return null; 97 } 98 99 byte[] bytes = new byte[4]; 100 String[] elements = text.split("\\.", -1); 101 try { 102 long l; 103 int i; 104 switch (elements.length) { 105 case 1: 106 l = Long.parseLong(elements[0]); 107 if ((l < 0L) || (l > 4294967295L)) { 108 return null; 109 } 110 bytes[0] = (byte) (int) (l >> 24 & 0xFF); 111 bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); 112 bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); 113 bytes[3] = (byte) (int) (l & 0xFF); 114 break; 115 case 2: 116 l = Integer.parseInt(elements[0]); 117 if ((l < 0L) || (l > 255L)) { 118 return null; 119 } 120 bytes[0] = (byte) (int) (l & 0xFF); 121 l = Integer.parseInt(elements[1]); 122 if ((l < 0L) || (l > 16777215L)) { 123 return null; 124 } 125 bytes[1] = (byte) (int) (l >> 16 & 0xFF); 126 bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); 127 bytes[3] = (byte) (int) (l & 0xFF); 128 break; 129 case 3: 130 for (i = 0; i < 2; ++i) { 131 l = Integer.parseInt(elements[i]); 132 if ((l < 0L) || (l > 255L)) { 133 return null; 134 } 135 bytes[i] = (byte) (int) (l & 0xFF); 136 } 137 l = Integer.parseInt(elements[2]); 138 if ((l < 0L) || (l > 65535L)) { 139 return null; 140 } 141 bytes[2] = (byte) (int) (l >> 8 & 0xFF); 142 bytes[3] = (byte) (int) (l & 0xFF); 143 break; 144 case 4: 145 for (i = 0; i < 4; ++i) { 146 l = Integer.parseInt(elements[i]); 147 if ((l < 0L) || (l > 255L)) { 148 return null; 149 } 150 bytes[i] = (byte) (int) (l & 0xFF); 151 } 152 break; 153 default: 154 return null; 155 } 156 } catch (NumberFormatException e) { 157 return null; 158 } 159 return bytes; 160 } 161 162 public static String getHostIp() { 163 try { 164 return InetAddress.getLocalHost().getHostAddress(); 165 } catch (UnknownHostException e) { 166 } 167 return "127.0.0.1"; 168 } 169 170 public static String getHostName() { 171 try { 172 return InetAddress.getLocalHost().getHostName(); 173 } catch (UnknownHostException e) { 174 } 175 return "未知"; 176 } 177 178 /** 179 * 校验IP有效性 180 * @param ip 181 * @return 182 */ 183 public static Boolean ipMatch(String ip){ 184 Pattern pattern = 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"); 185 Matcher matcher = pattern.matcher(ip); 186 if(!matcher.matches()){ 187 return Boolean.FALSE; 188 } 189 return Boolean.TRUE; 190 } 191 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了