懒羊羊
2024-01-31 e57a8990ae56f657a59c435a0613c5f7a8728003
提交 | 用户 | 时间
e57a89 1 package com.jcdm.common.utils.ip;
2
3 import java.net.InetAddress;
4 import java.net.UnknownHostException;
5 import javax.servlet.http.HttpServletRequest;
6 import com.jcdm.common.utils.ServletUtils;
7 import com.jcdm.common.utils.StringUtils;
8
9 /**
10  * 获取IP方法
11  * 
12  * @author jc
13  */
14 public class IpUtils
15 {
16     public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
17     // 匹配 ip
18     public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
19     public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
20     // 匹配网段
21     public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
22
23     /**
24      * 获取客户端IP
25      * 
26      * @return IP地址
27      */
28     public static String getIpAddr()
29     {
30         return getIpAddr(ServletUtils.getRequest());
31     }
32
33     /**
34      * 获取客户端IP
35      * 
36      * @param request 请求对象
37      * @return IP地址
38      */
39     public static String getIpAddr(HttpServletRequest request)
40     {
41         if (request == null)
42         {
43             return "unknown";
44         }
45         String ip = request.getHeader("x-forwarded-for");
46         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
47         {
48             ip = request.getHeader("Proxy-Client-IP");
49         }
50         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
51         {
52             ip = request.getHeader("X-Forwarded-For");
53         }
54         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
55         {
56             ip = request.getHeader("WL-Proxy-Client-IP");
57         }
58         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
59         {
60             ip = request.getHeader("X-Real-IP");
61         }
62
63         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
64         {
65             ip = request.getRemoteAddr();
66         }
67
68         return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
69     }
70
71     /**
72      * 检查是否为内部IP地址
73      * 
74      * @param ip IP地址
75      * @return 结果
76      */
77     public static boolean internalIp(String ip)
78     {
79         byte[] addr = textToNumericFormatV4(ip);
80         return internalIp(addr) || "127.0.0.1".equals(ip);
81     }
82
83     /**
84      * 检查是否为内部IP地址
85      * 
86      * @param addr byte地址
87      * @return 结果
88      */
89     private static boolean internalIp(byte[] addr)
90     {
91         if (StringUtils.isNull(addr) || addr.length < 2)
92         {
93             return true;
94         }
95         final byte b0 = addr[0];
96         final byte b1 = addr[1];
97         // 10.x.x.x/8
98         final byte SECTION_1 = 0x0A;
99         // 172.16.x.x/12
100         final byte SECTION_2 = (byte) 0xAC;
101         final byte SECTION_3 = (byte) 0x10;
102         final byte SECTION_4 = (byte) 0x1F;
103         // 192.168.x.x/16
104         final byte SECTION_5 = (byte) 0xC0;
105         final byte SECTION_6 = (byte) 0xA8;
106         switch (b0)
107         {
108             case SECTION_1:
109                 return true;
110             case SECTION_2:
111                 if (b1 >= SECTION_3 && b1 <= SECTION_4)
112                 {
113                     return true;
114                 }
115             case SECTION_5:
116                 switch (b1)
117                 {
118                     case SECTION_6:
119                         return true;
120                 }
121             default:
122                 return false;
123         }
124     }
125
126     /**
127      * 将IPv4地址转换成字节
128      * 
129      * @param text IPv4地址
130      * @return byte 字节
131      */
132     public static byte[] textToNumericFormatV4(String text)
133     {
134         if (text.length() == 0)
135         {
136             return null;
137         }
138
139         byte[] bytes = new byte[4];
140         String[] elements = text.split("\\.", -1);
141         try
142         {
143             long l;
144             int i;
145             switch (elements.length)
146             {
147                 case 1:
148                     l = Long.parseLong(elements[0]);
149                     if ((l < 0L) || (l > 4294967295L))
150                     {
151                         return null;
152                     }
153                     bytes[0] = (byte) (int) (l >> 24 & 0xFF);
154                     bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
155                     bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
156                     bytes[3] = (byte) (int) (l & 0xFF);
157                     break;
158                 case 2:
159                     l = Integer.parseInt(elements[0]);
160                     if ((l < 0L) || (l > 255L))
161                     {
162                         return null;
163                     }
164                     bytes[0] = (byte) (int) (l & 0xFF);
165                     l = Integer.parseInt(elements[1]);
166                     if ((l < 0L) || (l > 16777215L))
167                     {
168                         return null;
169                     }
170                     bytes[1] = (byte) (int) (l >> 16 & 0xFF);
171                     bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
172                     bytes[3] = (byte) (int) (l & 0xFF);
173                     break;
174                 case 3:
175                     for (i = 0; i < 2; ++i)
176                     {
177                         l = Integer.parseInt(elements[i]);
178                         if ((l < 0L) || (l > 255L))
179                         {
180                             return null;
181                         }
182                         bytes[i] = (byte) (int) (l & 0xFF);
183                     }
184                     l = Integer.parseInt(elements[2]);
185                     if ((l < 0L) || (l > 65535L))
186                     {
187                         return null;
188                     }
189                     bytes[2] = (byte) (int) (l >> 8 & 0xFF);
190                     bytes[3] = (byte) (int) (l & 0xFF);
191                     break;
192                 case 4:
193                     for (i = 0; i < 4; ++i)
194                     {
195                         l = Integer.parseInt(elements[i]);
196                         if ((l < 0L) || (l > 255L))
197                         {
198                             return null;
199                         }
200                         bytes[i] = (byte) (int) (l & 0xFF);
201                     }
202                     break;
203                 default:
204                     return null;
205             }
206         }
207         catch (NumberFormatException e)
208         {
209             return null;
210         }
211         return bytes;
212     }
213
214     /**
215      * 获取IP地址
216      * 
217      * @return 本地IP地址
218      */
219     public static String getHostIp()
220     {
221         try
222         {
223             return InetAddress.getLocalHost().getHostAddress();
224         }
225         catch (UnknownHostException e)
226         {
227         }
228         return "127.0.0.1";
229     }
230
231     /**
232      * 获取主机名
233      * 
234      * @return 本地主机名
235      */
236     public static String getHostName()
237     {
238         try
239         {
240             return InetAddress.getLocalHost().getHostName();
241         }
242         catch (UnknownHostException e)
243         {
244         }
245         return "未知";
246     }
247
248     /**
249      * 从多级反向代理中获得第一个非unknown IP地址
250      *
251      * @param ip 获得的IP地址
252      * @return 第一个非unknown IP地址
253      */
254     public static String getMultistageReverseProxyIp(String ip)
255     {
256         // 多级反向代理检测
257         if (ip != null && ip.indexOf(",") > 0)
258         {
259             final String[] ips = ip.trim().split(",");
260             for (String subIp : ips)
261             {
262                 if (false == isUnknown(subIp))
263                 {
264                     ip = subIp;
265                     break;
266                 }
267             }
268         }
269         return StringUtils.substring(ip, 0, 255);
270     }
271
272     /**
273      * 检测给定字符串是否为未知,多用于检测HTTP请求相关
274      *
275      * @param checkString 被检测的字符串
276      * @return 是否未知
277      */
278     public static boolean isUnknown(String checkString)
279     {
280         return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
281     }
282
283     /**
284      * 是否为IP
285      */
286     public static boolean isIP(String ip)
287     {
288         return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
289     }
290
291     /**
292      * 是否为IP,或 *为间隔的通配符地址
293      */
294     public static boolean isIpWildCard(String ip)
295     {
296         return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
297     }
298
299     /**
300      * 检测参数是否在ip通配符里
301      */
302     public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
303     {
304         String[] s1 = ipWildCard.split("\\.");
305         String[] s2 = ip.split("\\.");
306         boolean isMatchedSeg = true;
307         for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
308         {
309             if (!s1[i].equals(s2[i]))
310             {
311                 isMatchedSeg = false;
312                 break;
313             }
314         }
315         return isMatchedSeg;
316     }
317
318     /**
319      * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
320      */
321     public static boolean isIPSegment(String ipSeg)
322     {
323         return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
324     }
325
326     /**
327      * 判断ip是否在指定网段中
328      */
329     public static boolean ipIsInNetNoCheck(String iparea, String ip)
330     {
331         int idx = iparea.indexOf('-');
332         String[] sips = iparea.substring(0, idx).split("\\.");
333         String[] sipe = iparea.substring(idx + 1).split("\\.");
334         String[] sipt = ip.split("\\.");
335         long ips = 0L, ipe = 0L, ipt = 0L;
336         for (int i = 0; i < 4; ++i)
337         {
338             ips = ips << 8 | Integer.parseInt(sips[i]);
339             ipe = ipe << 8 | Integer.parseInt(sipe[i]);
340             ipt = ipt << 8 | Integer.parseInt(sipt[i]);
341         }
342         if (ips > ipe)
343         {
344             long t = ips;
345             ips = ipe;
346             ipe = t;
347         }
348         return ips <= ipt && ipt <= ipe;
349     }
350
351     /**
352      * 校验ip是否符合过滤串规则
353      * 
354      * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
355      * @param ip 校验IP地址
356      * @return boolean 结果
357      */
358     public static boolean isMatchedIp(String filter, String ip)
359     {
360         if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
361         {
362             return false;
363         }
364         String[] ips = filter.split(";");
365         for (String iStr : ips)
366         {
367             if (isIP(iStr) && iStr.equals(ip))
368             {
369                 return true;
370             }
371             else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
372             {
373                 return true;
374             }
375             else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
376             {
377                 return true;
378             }
379         }
380         return false;
381     }
382 }