All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javaweb.utils.IpSearch Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
package org.javaweb.utils;

import java.io.File;
import java.io.InputStream;
import java.util.Arrays;

/**
 * qqzeng IP解析库 https://www.qqzeng.com/
 */
public class IpSearch {

	private static int[] prefStart = new int[256];

	private static int[] prefEnd = new int[256];

	private static long[] endArr;

	private static String[] addrArr;

	private static byte[] data;

	private static String ipFileName = "qqzeng-ip-3.0-ultimate.dat";

	private static File ipFile = new File(FileUtils.getCurrentDirectory(), ipFileName);

	static {
		try {
			InputStream in = IPLocationUtils.class.getClass().getResourceAsStream("/" + ipFileName);
			if (in != null) {
				data = IOUtils.toByteArray(in);
			}

			if (data == null && ipFile.exists()) {
				data = FileUtils.readFileToByteArray(ipFile);
			}

			for (int i = 0; i < 256; i++) {
				int j = i * 8 + 4;

				prefStart[i] = (int) bytesToLong(data[j], data[j + 1], data[j + 2], data[j + 3]);
				prefEnd[i] = (int) bytesToLong(data[j + 4], data[j + 5], data[j + 6], data[j + 7]);
			}

			int recordSize = (int) bytesToLong(data[0], data[1], data[2], data[3]);
			endArr = new long[recordSize];
			addrArr = new String[recordSize];

			for (int i = 0; i < recordSize; i++) {
				int  p        = 2052 + (i * 8);
				long endIpNum = bytesToLong(data[p], data[1 + p], data[2 + p], data[3 + p]);

				int offset = (int) bytesToLong3(data[4 + p], data[5 + p], data[6 + p]);
				int length = data[7 + p] & 0xff;

				endArr[i] = endIpNum;

				addrArr[i] = new String(Arrays.copyOfRange(data, offset, offset + length));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 查找IP地址对应的真实地理位置信息
	 *
	 * @param ip
	 * @return
	 */
	public static IPLocation find(String ip) {
		if (IPV4Utils.isValid(ip)) {
			String[] ips      = ip.split("\\.");
			int      prefix   = Integer.valueOf(ips[0]);
			long     val      = ipToLong(ip);
			int      low      = prefStart[prefix];
			int      high     = prefEnd[prefix];
			long     cur      = low == high ? low : binarySearch(low, high, val);
			String   location = addrArr[(int) cur];

			if (location != null) {
				String[] strs = location.split("\\|", -1);

				if (strs.length == 11) {
					return new IPLocation(
							strs[8], strs[7], strs[1], strs[2], strs[3],
							strs[4], strs[5], strs[9], strs[10]
					);
				}
			}
		}

		return null;
	}

	private static int binarySearch(int low, int high, long k) {
		int m = 0;
		while (low <= high) {
			int mid = (low + high) / 2;

			long endIpNum = endArr[mid];
			if (endIpNum >= k) {
				m = mid;
				if (mid == 0) {
					break;
				}

				high = mid - 1;
			} else {
				low = mid + 1;
			}
		}

		return m;
	}

	private static long bytesToLong(byte a, byte b, byte c, byte d) {
		return (a & 0xFFL) | ((b << 8) & 0xFF00L) | ((c << 16) & 0xFF0000L) | ((d << 24) & 0xFF000000L);

	}

	private static long bytesToLong3(byte a, byte b, byte c) {
		return (a & 0xFFL) | ((b << 8) & 0xFF00L) | ((c << 16) & 0xFF0000L);
	}

	public static long ipToLong(String ip) {
		long     result = 0;
		String[] d      = ip.split("\\.");

		for (String b : d) {
			result <<= 8;
			result |= Long.parseLong(b) & 0xff;
		}

		return result;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy