像我们这种开发网站的免不了跟IP打交道,我们经常需要搞清楚某个IP地址是谁在使用它。因此,我们需要一种能够将IP地址翻译成有意义的信息的方法。这就是IP库存在的意义,本文搜集了互联网上所有的离线IP库:zxipv6wryIp2regionGeoipIp2location纯真IP库 当然有的里面信息可能已经过时或不准确。此处给出如何使用Java来调用这些IP库

库信息概览

库名 支持的IP类型 是否持续更新 备注
ip2location IPv4 / IPv6 ✅ 是 商业数据库,但是提供Lite免费版本,仅提供Bin格式数据库。
GeoIP IPv4 / IPv6 ✅ 是 MaxMind 提供,传统 GeoIP(旧版)已停止更新,GeoIP2(付费)每月更新,免费版(GeoLite2)每月更新。
ip2region IPv4 ✅ 是 开源项目(GitHub维护),支持IPv4,更新依赖社区贡献,近年活跃度较高。
纯真社区IP库 IPv4 / IPv6 ✅ 是 纯真数据库是国内首屈一指的数据库,其提供的离线IP库只要你通过授权就可以一直免费使用,每周三更新一次.
zxipv6wry IPv6 ❌ 否 专为IPv6设计的离线库,已停止更新。

Ip2location

https://github.com/renfei/ip2location

官网地址

https://www.ip2location.com/

Maven地址

<dependency>
    <groupId>net.renfei</groupId>
    <artifactId>ip2location</artifactId>
    <version>1.2.4</version>
</dependency>

其实这个库导的没有必要,这只是他方便我们使用写的我们完全可以直接把他代码扣下来用,并且自主实现AutoCloseable,这里仅仅演示我们就不这样干了直接使用官方提供的 Maven 依赖项即可。

创建IPInfo

package com.zftj.IP2Location;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
 * IP信息对象类,用于封装IP查询结果
 * @author 17Yuns
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class IPInfo {

    // 查询的IP地址
    private String ip;

    // 国家代码(ISO 3166-1 Alpha-2)
    @JsonProperty("country_code")
    private String countryCode;

    // 国家全名
    @JsonProperty("country_name")
    private String countryName;

    // 省份/地区名称
    private String region;

    // 城市名称
    private String city;

    // 互联网服务提供商
    private String isp;

    // 纬度
    private String latitude;

    // 经度
    private String longitude;

    // IP所属域名
    private String domain;

    // 邮政编码
    private String zipcode;

    // 时区名称
    private String timezone;

    // 网络连接速度
    private String netspeed;

    // 自治系统编号(ASN)
    private String asn;

    // 用途类型(如 CDN、Dialup 等)
    private String usagetype;

    // 地址类型(如 Unicast、Multicast 等)
    @JsonProperty("addresstype")
    private String addressType;

    // 类别(如 ISP、Hosting 等)
    private String category;

    // 行政区/区域名称
    private String district;

    // 海拔高度(单位:米)
    private String elevation;

    // 移动运营商品牌
    private String mobilebrand;

    // 国际电话区号
    @JsonProperty("iddcode")
    private String iddCode;

    // 国内电话区号
    @JsonProperty("areacode")
    private String areaCode;

    // 气象站代码
    @JsonProperty("weatherstationcode")
    private String weatherStationCode;

    // 气象站名称
    @JsonProperty("weatherstationname")
    private String weatherStationName;

    // 移动网络代码(MCC)
    private String mcc;

    // 移动网络代码(MNC)
    private String mnc;

    // 数据库版本信息
    private String version;
}

创建IPError

package com.zftj.IP2Location;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

/**
 * 错误信息对象类
 * @author 17Yuns
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class IPError {

    // 错误状态码(如 INVALID_IP_ADDRESS)
    private String status;

    // 错误描述信息(如 "Invalid IP address.")
    private String error;

    // 出错的IP地址
    private String ip;

    public IPError(String status, String errorMessage, String ip) {
    }
}

创建Main

package com.zftj.IP2Location;

import com.fasterxml.jackson.databind.ObjectMapper;
import net.renfei.ip2location.IP2Location;
import net.renfei.ip2location.IPResult;
import net.renfei.ip2location.IPTools;

import java.util.Map;

/**
 * @author 17Yuns
 * @version 1.0
 */
public class Main {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    private static final Map<String, String> ERROR_MESSAGES = Map.of(
            "EMPTY_IP_ADDRESS", "IP address cannot be blank.",
            "INVALID_IP_ADDRESS", "Invalid IP address.",
            "MISSING_FILE", "Invalid database path.",
            "IPV6_NOT_SUPPORTED", "This BIN does not contain IPv6 data."
    );

    private static final String DB11_V4 = "src/main/resources/ipdata/ip2location/IP2LOCATION-LITE-DB11.bin";
    private static final String DB11_V6 = "src/main/resources/ipdata/ip2location/IP2LOCATION-LITE-DB11.IPV6.bin";

    public static void main(String[] args) {
        IP2Location loc = new IP2Location();
        String binfile = null;
        try {
            String ip = "23.214.45.23";
            boolean isIPv4 = new IPTools().IsIPv4(ip);
            binfile = isIPv4 ? DB11_V4 : DB11_V6;

            loc.Open(binfile, true);
            IPResult rec = loc.IPQuery(ip);

            if ("OK".equals(rec.getStatus())) {
                IPInfo info = getIpInfo(ip, rec);
                System.out.println(toJson(info));
            } else {
                IPError error = getIpError(rec, ip);
                System.out.println(toJson(error));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            loc.Close();
        }
    }

    private static IPInfo getIpInfo(String ip, IPResult rec) {
        IPInfo info = new IPInfo();
        info.setIp(ip);
        info.setCountryCode(rec.getCountryShort());
        info.setCountryName(rec.getCountryLong());
        info.setRegion(rec.getRegion());
        info.setCity(rec.getCity());
        info.setIsp(rec.getISP());
        info.setLatitude(String.valueOf(rec.getLatitude()));
        info.setLongitude(String.valueOf(rec.getLongitude()));
        info.setDomain(rec.getDomain());
        info.setZipcode(rec.getZipCode());
        info.setTimezone(rec.getTimeZone());
        info.setNetspeed(rec.getNetSpeed());
        info.setAsn(rec.getASN());
        info.setUsagetype(rec.getUsageType());
        info.setAddressType(rec.getAddressType());
        info.setCategory(rec.getCategory());
        info.setDistrict(rec.getDistrict());
        info.setElevation(String.valueOf(rec.getElevation()));
        info.setMobilebrand(rec.getMobileBrand());
        info.setIddCode(rec.getIDDCode());
        info.setAreaCode(rec.getAreaCode());
        info.setWeatherStationCode(rec.getWeatherStationCode());
        info.setWeatherStationName(rec.getWeatherStationName());
        info.setMcc(rec.getMCC());
        info.setMnc(rec.getMNC());
        info.setVersion(rec.getVersion());
        return info;
    }

    private static IPError getIpError(IPResult rec, String ip) {
        String errorMessage = ERROR_MESSAGES.getOrDefault(rec.getStatus(), "Unknown error: " + rec.getStatus());
        return new IPError(rec.getStatus(), errorMessage, ip);
    }
    private static String toJson(Object obj) {
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException("JSON序列化失败", e);
        }
    }

}

运行结果

{
    "ip": "23.214.45.23",
    "region": "New South Wales",
    "city": "Sydney",
    "isp": "Not_Supported",
    "latitude": "-33.86778",
    "longitude": "151.20705",
    "domain": "Not_Supported",
    "zipcode": "2000",
    "timezone": "+10:00",
    "netspeed": "Not_Supported",
    "asn": "Not_Supported",
    "usagetype": "Not_Supported",
    "category": "Not_Supported",
    "district": "Not_Supported",
    "elevation": "0.0",
    "mobilebrand": "Not_Supported",
    "mcc": "Not_Supported",
    "mnc": "Not_Supported",
    "version": "Version 8.11.2",
    "country_code": "AU",
    "country_name": "Australia",
    "addresstype": "Not_Supported",
    "iddcode": "Not_Supported",
    "areacode": "Not_Supported",
    "weatherstationcode": "Not_Supported",
    "weatherstationname": "Not_Supported"
}

Ip2region

这也是非常优秀的IP库,官方实例写的非常清楚,此处仅做总结

https://github.com/lionsoul2014/ip2region

Maven仓库

<dependency>
    <groupId>org.lionsoul</groupId>
    <artifactId>ip2region</artifactId>
    <version>2.7.0</version>
</dependency>

创建Main

package com.zftj.ip2region;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.lionsoul.ip2region.xdb.Searcher;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 17Yuns
 * @version 1.0
 */
public class Main {
    public static void main(String[] args) throws IOException {
        // 使用 ClassLoader 加载 resources 下的 ip2region.xdb 文件
        String dbPath;
        try (InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("ipdata/ip2region/ip2region.xdb")) {
            if (inputStream == null) {
                System.out.println("Failed to load ip2region.xdb from resources.");
                return;
            }
            // 将资源文件复制到临时文件
            Path tempFile = Files.createTempFile("ip2region", ".xdb");
            Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
            dbPath = tempFile.toAbsolutePath().toString();
        } catch (Exception e) {
            System.out.printf("Failed to load ip2region.xdb: %s\n", e);
            return;
        }

        // 1、从 dbPath 中预先加载 VectorIndex 缓存,并且把这个得到的数据作为全局变量,后续反复使用。
        byte[] vIndex;
        try {
            vIndex = Searcher.loadVectorIndexFromFile(dbPath);
        } catch (Exception e) {
            System.out.printf("failed to load vector index from `%s`: %s\n", dbPath, e);
            return;
        }

        // 2、使用全局的 vIndex 创建带 VectorIndex 缓存的查询对象。
        Searcher searcher;
        try {
            searcher = Searcher.newWithVectorIndex(dbPath, vIndex);
        } catch (Exception e) {
            System.out.printf("failed to create vectorIndex cached searcher with `%s`: %s\n", dbPath, e);
            return;
        }

        // 3、查询
        String ip = null;
        try {
            ip = "23.214.45.23";
            String region = searcher.search(ip);
          //  System.out.printf("{region: %s, ioCount: %d, took: %d μs}\n", region, searcher.getIOCount(), cost);

            // 解析结果并输出JSON
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("ip", ip);
            resultMap.put("region", region);
            resultMap.putAll(parseIp2RegionResult(region));

            // 转换为JSON输出
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonResult = objectMapper.writeValueAsString(resultMap);
            System.out.println(jsonResult);
        } catch (Exception e) {
            System.out.printf("failed to search(%s): %s\n", ip, e);
        }

        // 4、关闭资源
        searcher.close();
    }

    /**
     * 解析 ip2region 返回的结果字符串
     * 格式通常为: "国家|区域|城市|运营商|ISP"
     */
    private static Map<String, String> parseIp2RegionResult(String region) {
        Map<String, String> result = new HashMap<>();

        if (region == null || region.isEmpty()) {
            return result;
        }

        String[] parts = region.split("\\|");

        if (parts.length >= 1) {
            String country = parts[0].trim();
            if (!"0".equals(country)) {
                result.put("country", country);
            }
        }

        if (parts.length >= 2) {
            String area = parts[1].trim();
            if (!"0".equals(area)) {
                result.put("area", area);
            }
        }

        if (parts.length >= 3) {
            String city = parts[2].trim();
            if (!"0".equals(city)) {
                result.put("city", city);
            }
        }

        if (parts.length >= 4) {
            String provider = parts[3].trim();
            if (!"0".equals(provider)) {
                result.put("provider", provider);
            }
        }

        if (parts.length >= 5) {
            String isp = parts[4].trim();
            if (!"0".equals(isp)) {
                result.put("isp", isp);
            }
        }

        return result;
    }
}

运行结果

{"country":"美国","city":"德克萨斯","provider":"达拉斯","ip":"23.214.45.23","isp":"阿卡迈","region":"美国|0|德克萨斯|达拉斯|阿卡迈"}

GEOIP库

本文章采用的是大佬修改后的版本以及官方版,统一进行查询在不同字段下进行展示,这个库信息提供的挺多的

https://github.com/Loyalsoldier/geoip

Maven库

 <dependency>
    <groupId>com.maxmind.geoip2</groupId>
    <artifactId>geoip2</artifactId>
    <version>4.2.1</version>
</dependency>
<dependency>
    <groupId>com.maxmind.db</groupId>
    <artifactId>maxmind-db</artifactId>
    <version>2.0.0</version>
</dependency>

创建GeoIpService

package com.zftj.geoip;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.AddressNotFoundException;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;

/**
 * 使用MaxMind数据库进行IP地理位置查询的服务
 *
 * @author 17Yuns
 * @version 1.1
 */
public class GeoIpService implements Closeable {
    private static final String RESOURCE_PATH = "ipdata/geoip/";

    private final ObjectMapper objectMapper;
    private final DatabaseReader countryReader;
    private final DatabaseReader asnReader;
    private final DatabaseReader countryWithoutAsnReader;
    private final DatabaseReader countryAsnReader;

    /**
     * 创建新的GeoIpService实例并初始化数据库读取器
     *
     * @throws IOException 如果数据库文件无法加载
     */
    public GeoIpService() throws IOException {
        this.objectMapper = new ObjectMapper();

        // 初始化数据库读取器
        this.countryReader = createReader(RESOURCE_PATH + "GeoLite2-Country.mmdb");
        this.asnReader = createReader(RESOURCE_PATH + "GeoLite2-ASN.mmdb");
        this.countryWithoutAsnReader = createReader(RESOURCE_PATH + "Country-without-asn.mmdb");
        this.countryAsnReader = createReader(RESOURCE_PATH + "Country-asn.mmdb");
    }

    /**
     * 从资源文件创建DatabaseReader的辅助方法
     */
    private DatabaseReader createReader(String resourcePath) throws IOException {
        InputStream is = getClass().getClassLoader().getResourceAsStream(resourcePath);
        if (is == null) {
            throw new IOException("未找到资源: " + resourcePath);
        }
        return new DatabaseReader.Builder(is).build();
    }

    /**
     * 查询IP地址的地理位置数据并以JSON字符串形式返回
     *
     * @param ipAddress 要查询的IP地址
     * @return 包含地理位置数据的JSON字符串
     * @throws Exception 如果查询失败
     */
    public String lookupIp(String ipAddress) throws Exception {
        InetAddress ipAddr = InetAddress.getByName(ipAddress);

        // 创建根JSON结构
        ObjectNode rootNode = objectMapper.createObjectNode();
        ObjectNode geoipNode = objectMapper.createObjectNode();
        ObjectNode normalNode = objectMapper.createObjectNode();
        ObjectNode plusNode = objectMapper.createObjectNode();

        // 填充普通数据
        addLookupResult(normalNode, "country", () -> countryReader.country(ipAddr));
        addLookupResult(normalNode, "asn", () -> asnReader.asn(ipAddr));

        // 填充plus数据
        addLookupResult(plusNode, "country", () -> countryWithoutAsnReader.country(ipAddr));
        addLookupResult(plusNode, "asn", () -> countryAsnReader.country(ipAddr));

        // 仅将非空节点添加到结果中
        if (!normalNode.isEmpty()) {
            geoipNode.set("normal", normalNode);
        }

        if (!plusNode.isEmpty()) {
            geoipNode.set("plus", plusNode);
        }

        rootNode.set("geoip", geoipNode);

        return objectMapper.writeValueAsString(rootNode);
    }

    /**
     * 将查询结果添加到JSON节点的辅助方法,处理异常
     */
    private <T> void addLookupResult(ObjectNode parentNode, String key, LookupOperation<T> operation) {
        try {
            T result = operation.lookup();
            if (result != null) {
                JsonNode jsonNode = objectMapper.valueToTree(result);
                parentNode.set(key, jsonNode);
            }
        } catch (AddressNotFoundException e) {
            // IP在数据库中未找到,跳过此结果
        } catch (Exception e) {
            // 记录错误但继续处理其他查询
            e.printStackTrace();
        }
    }

    /**
     * IP查询的函数式接口
     */
    @FunctionalInterface
    private interface LookupOperation<T> {
        T lookup() throws Exception;
    }

    @Override
    public void close() {
        try {
            countryReader.close();
            asnReader.close();
            countryWithoutAsnReader.close();
            countryAsnReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

创建Main

package com.zftj.geoip;

/**
 * @author 17Yuns
 * @version 1.0
 */
public class Main {
    public static void main(String[] args) {
        try (GeoIpService service = new GeoIpService()) {
            String ipAddress = "23.214.45.23";
            String result = service.lookupIp(ipAddress);
            System.out.println(result);
        } catch (Exception e) {
            System.err.println("处理IP查询时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

运行结果

{
    "geoip": {
        "normal": {
            "country": {
                "continent": {
                    "code": "OC",
                    "geoname_id": 6255151,
                    "names": {
                        "de": "Ozeanien",
                        "ru": "Океания",
                        "pt-BR": "Oceania",
                        "ja": "オセアニア",
                        "en": "Oceania",
                        "fr": "Océanie",
                        "zh-CN": "大洋洲",
                        "es": "Oceanía"
                    }
                },
                "country": {
                    "confidence": null,
                    "geoname_id": 2077456,
                    "is_in_european_union": false,
                    "iso_code": "AU",
                    "names": {
                        "de": "Australien",
                        "ru": "Австралия",
                        "pt-BR": "Austrália",
                        "ja": "オーストラリア",
                        "en": "Australia",
                        "fr": "Australie",
                        "zh-CN": "澳大利亚",
                        "es": "Australia"
                    }
                },
                "maxmind": {
                    "queries_remaining": null
                },
                "registered_country": {
                    "confidence": null,
                    "geoname_id": 6252001,
                    "is_in_european_union": false,
                    "iso_code": "US",
                    "names": {
                        "de": "USA",
                        "ru": "США",
                        "pt-BR": "EUA",
                        "ja": "アメリカ",
                        "en": "United States",
                        "fr": "États Unis",
                        "zh-CN": "美国",
                        "es": "Estados Unidos"
                    }
                },
                "represented_country": {
                    "confidence": null,
                    "geoname_id": null,
                    "is_in_european_union": false,
                    "iso_code": null,
                    "names": {},
                    "type": null
                },
                "traits": {
                    "autonomous_system_number": null,
                    "autonomous_system_organization": null,
                    "connection_type": null,
                    "domain": null,
                    "ip_address": "23.214.45.23",
                    "is_anonymous": false,
                    "is_anonymous_proxy": false,
                    "is_anonymous_vpn": false,
                    "is_anycast": false,
                    "is_hosting_provider": false,
                    "is_legitimate_proxy": false,
                    "is_public_proxy": false,
                    "is_residential_proxy": false,
                    "is_satellite_provider": false,
                    "is_tor_exit_node": false,
                    "isp": null,
                    "mobile_country_code": null,
                    "mobile_network_code": null,
                    "network": "23.214.32.0/19",
                    "organization": null,
                    "user_type": null,
                    "user_count": null,
                    "static_ip_score": null
                }
            },
            "asn": {
                "autonomous_system_number": 16625,
                "autonomous_system_organization": "AKAMAI-AS",
                "ip_address": "23.214.45.23",
                "network": "23.214.32.0/19"
            }
        },
        "plus": {
            "country": {
                "continent": {
                    "code": null,
                    "geoname_id": null,
                    "names": {}
                },
                "country": {
                    "confidence": null,
                    "geoname_id": 2077456,
                    "is_in_european_union": false,
                    "iso_code": "AU",
                    "names": {
                        "de": "Australien",
                        "ru": "Австралия",
                        "pt-BR": "Austrália",
                        "ja": "オーストラリア",
                        "en": "Australia",
                        "fr": "Australie",
                        "zh-CN": "澳大利亚",
                        "es": "Australia"
                    }
                },
                "maxmind": {
                    "queries_remaining": null
                },
                "registered_country": {
                    "confidence": null,
                    "geoname_id": null,
                    "is_in_european_union": false,
                    "iso_code": null,
                    "names": {}
                },
                "represented_country": {
                    "confidence": null,
                    "geoname_id": null,
                    "is_in_european_union": false,
                    "iso_code": null,
                    "names": {},
                    "type": null
                },
                "traits": {
                    "autonomous_system_number": null,
                    "autonomous_system_organization": null,
                    "connection_type": null,
                    "domain": null,
                    "ip_address": "23.214.45.23",
                    "is_anonymous": false,
                    "is_anonymous_proxy": false,
                    "is_anonymous_vpn": false,
                    "is_anycast": false,
                    "is_hosting_provider": false,
                    "is_legitimate_proxy": false,
                    "is_public_proxy": false,
                    "is_residential_proxy": false,
                    "is_satellite_provider": false,
                    "is_tor_exit_node": false,
                    "isp": null,
                    "mobile_country_code": null,
                    "mobile_network_code": null,
                    "network": "23.214.32.0/19",
                    "organization": null,
                    "user_type": null,
                    "user_count": null,
                    "static_ip_score": null
                }
            }
        }
    }
}

CZ88(纯真数据库)

官方实例写的也很清晰,此处简要提及

https://cz88.net/geo-public https://github.com/tagphi/czdb-search-java

Maven库

<dependency>
    <groupId>net.cz88</groupId>
    <artifactId>czdb-search</artifactId>
    <version>1.0.2.7</version>
</dependency>

创建Main

package com.zftj.czdb;

import com.fasterxml.jackson.databind.ObjectMapper;
import net.cz88.czdb.DbSearcher;
import net.cz88.czdb.QueryType;
import net.renfei.ip2location.IPTools;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 17Yuns
 * @version 1.0
 */
public class Main {
    public static void main(String[] args) throws Exception {
        String ip = "23.224.56.23";
        String key = "";//这个key你得自己去申请
        boolean isIPv4 = new IPTools().IsIPv4(ip);
        String dbPath=null;
        if (isIPv4){
            dbPath="src/main/resources/ipdata/czdb/cz88_public_v4.czdb";
        }else {
            dbPath="src/main/resources/ipdata/czdb/cz88_public_v6.czdb";
        }
        DbSearcher searcher = new DbSearcher(dbPath, QueryType.MEMORY, key);

        try {
            String region = searcher.search(ip);

            // 创建结果Map
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("ip", ip);
            resultMap.put("region", region);

            // 灵活处理不同格式的返回结果
            Map<String, String> parsedFields = parseRegion(region);
            resultMap.putAll(parsedFields);

            // 转换为JSON字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonResult = objectMapper.writeValueAsString(resultMap);

            // 输出JSON字符串
            System.out.println(jsonResult);
        } finally {
            searcher.close();
        }
    }

    private static Map<String, String> parseRegion(String region) {
        Map<String, String> result = new HashMap<>();

        if (region.contains("–")) {
            // 处理标准格式 "国家–省份–城市–区域 ISP"
            String[] parts = region.split("–");
            if (parts.length >= 1) {
                result.put("country", parts[0].trim());
            }
            if (parts.length >= 2) {
                result.put("province", parts[1].trim());
            }
            if (parts.length >= 3) {
                result.put("city", parts[2].trim());
            }

            if (parts.length >= 4) {
                String areaIsp = parts[3].trim();
                // 首先检查是否含有制表符
                int tabIndex = areaIsp.indexOf("\t");
                if (tabIndex > 0) {
                    result.put("area", areaIsp.substring(0, tabIndex).trim());
                    result.put("isp", areaIsp.substring(tabIndex + 1).trim());
                } else {
                    // 再检查是否含有空格
                    int spaceIndex = areaIsp.indexOf(" ");
                    if (spaceIndex > 0) {
                        result.put("area", areaIsp.substring(0, spaceIndex).trim());
                        result.put("isp", areaIsp.substring(spaceIndex + 1).trim());
                    } else {
                        result.put("area", areaIsp);
                    }
                }
            }
        } else if (region.contains("\t")) {
            // 处理类似 "澳大利亚\tAPNIC_Debogon-prefix网络" 的格式
            String[] parts = region.split("\t");
            if (parts.length >= 1) {
                result.put("country", parts[0].trim());
            }
            if (parts.length >= 2) {
                result.put("network", parts[1].trim());
            }
        } else if (region.contains(" ")) {
            // 处理简单的空格分隔形式
            int spaceIndex = region.indexOf(" ");
            result.put("country", region.substring(0, spaceIndex).trim());
            result.put("info", region.substring(spaceIndex + 1).trim());
        } else {
            // 无法分割的情况
            result.put("info", region.trim());
        }

        return result;
    }
}

运行结果

{
    "area": "洛杉矶",
    "country": "美国",
    "province": "加利福尼亚州",
    "city": "洛杉矶",
    "ip": "23.224.56.23",
    "isp": "Coperation_Coloction数据中心",
    "region": "美国–加利福尼亚州–洛杉矶–洛杉矶\tCoperation_Coloction数据中心"
}

ZXIPV6WRY

这个库仅支持IPv6并且已经停止更新了,搞这个其实意义不大

https://ip.zxinc.org/

下载地址:

https://ip.zxinc.org/ip.7z

里面有很详细的各语言调用方法。

IP库下载地址

本博客书写之时已经下载过一遍,因为文件过大,便不在浪费服务器资源采用百度网盘的方式,口令为本站域名。当然纯真数据库我已经删除,请去自行获取授权