亚洲所有相关分配的IP段可以从 http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest 查询。
从里面解释后即可实现判断IP是否为中国。
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
public class IpUtil {
private static final String FILE_NAME = "delegated-apnic-latest";
// 只存放属于中国的ip段
private static Map> chinaIps = Maps.newHashMap();
static {
init();
}
public static void init() {
try {
// ip格式: add1.add2.add3.add4
// key为 : add1*256+add2
// value为int[2]: int[0]存的add3*256+add4的开始ip int[4]存的结束ip
Map> map = Maps.newHashMap();
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream(FILE_NAME);
List lines = IOUtils.readLines(input, StandardCharsets.UTF_8);
for (String line : lines) {
if (line.startsWith("apnic|CN|ipv4|")) {
// 只处理属于中国的ipv4地址
String[] strs = line.split("\\|");
String ip = strs[3];
String[] add = ip.split("\\.");
int count = Integer.valueOf(strs[4]);
int startIp = Integer.parseInt(add[0]) * 256 + Integer.parseInt(add[1]);
while (count > 0) {
if (count >= 65536) {
// add1,add2 整段都是中国ip
chinaIps.put(startIp, Collections.EMPTY_LIST);
count -= 65536;
startIp += 1;
} else {
int[] ipRange = new int[2];
ipRange[0] = Integer.parseInt(add[2]) * 256 + Integer.parseInt(add[3]);
ipRange[1] = ipRange[0] + count;
count -= count;
List list = map.get(startIp);
if (list == null) {
list = Lists.newArrayList();
map.put(startIp, list);
}
list.add(ipRange);
}
}
}
}
chinaIps = map;
} catch (Exception e) {
logger.error("ERROR", e);
}
}
public static boolean isChinaIp(String ip) {
if (StringUtils.isEmpty(ip)) {
return false;
}
String[] strs = ip.split("\\.");
if (strs.length != 4) {
return false;
}
int key = Integer.valueOf(strs[0]) * 256 + Integer.valueOf(strs[1]);
List list = chinaIps.get(key);
if (list == null) {
return false;
}
if (list.size() == 0) {
// 整段都是中国ip
return true;
}
int ipValue = Integer.valueOf(strs[2]) * 256 + Integer.valueOf(strs[3]);
for (int[] ipRange : list) {
if (ipValue >= ipRange[0] && ipValue <= ipRange[1]) {
return true;
}
}
return false;
}
private static final Logger logger = LoggerFactory.getLogger(IpUtil.class);
}