IPUtils.java 10 KB

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