DAT format access code

IPv6 access code:

import java.io.IOException;
import java.math.BigInteger;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

public class Ip {

    private Map<Long, Long> prefStart = new HashMap<>();
    private Map<Long, Long> prefEnd = new HashMap<>();
    private BigInteger[] endArr;
    private String[] addrArr;

    private static Ip instance = null;

    private Ip(String filePath) throws IOException {
        Path path = Paths.get(filePath);

        byte[] data = null;
        try {
            data = Files.readAllBytes(path);
        } catch (IOException e) {
            throw new IOException("file not found" + e);
        }

        long numbers = unpackInt4byte(data[4], data[5], data[6], data[7]);

        for (int k = 0; k < numbers; k++) {
            int i = k * 12 + 4 + 4;
            prefStart.put(unpackInt4byte(data[i + 8], data[i + 9], data[i + 10], data[i + 11]), unpackInt4byte(data[i], data[i + 1], data[i + 2], data[i + 3]));

            prefEnd.put(unpackInt4byte(data[i + 8], data[i + 9], data[i + 10], data[i + 11]), unpackInt4byte(data[i + 4], data[i + 5], data[i + 6], data[i + 7]));

        }

        int recordSize = (int) unpackInt4byte(data[0], data[1], data[2], data[3]);
        endArr = new BigInteger[recordSize];
        addrArr = new String[recordSize];
        for (int i = 0; i < recordSize; i++) {
            int p = (int) numbers * 12 + 4 + 4 + (i * 55);
//            long endipnum = unpackInt4byte(data[p+50], data[1 + p+50], data[2 + p+50], data[3 + p+50]);

            int offset = (int) unpackInt4byte(data[50 + p], data[50 + p + 1], data[50 + p + 2], data[50 + p + 3]);
            int length = data[50 + p + 4] & 0xff;
            BigInteger endipnum = new BigInteger(new String(Arrays.copyOfRange(data, p, p + 50)).replaceAll("\\*", ""));
            endArr[i] = endipnum;

            addrArr[i] = new String(Arrays.copyOfRange(data, offset, (offset + length)));
        }

    }

    public static synchronized Ip getInstance(String path) throws IOException {
        if (instance == null)
            instance = new Ip(path);
        return instance;
    }

    public String get(String ip) {
        try {

            InetAddress inetAddress = InetAddress.getByName(ip);
            if (!(inetAddress instanceof Inet6Address)) {
                throw new IllegalArgumentException("Not an IPv6 address: " + ip);
            }
            ip = inetAddress.getHostAddress();
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid IPv6 address: " + ip, e);
        }
        if (ip.contains("%")) {
            ip = ip.split("%")[0];
        }
        String[] ips = ip.split("\\:");
        long pref = Long.parseLong(ips[0], 16);
        BigInteger val = stringToBigInt(ip);
        if (prefStart.get(pref) == null || prefEnd.get(pref) == null) {
            return "保留|保留|||||||||||||||||";
        }
        long low = prefStart.get(pref), high = prefEnd.get(pref);
        long cur = low == high ? low : search(low, high, val);
        return addrArr[(int) cur];

    }

    private int search(long low, long high, BigInteger k) {
        int M = 0;
        while (low <= high) {
            int mid = (int) (low + high) / 2;

            BigInteger endipNum = endArr[mid];
            if (endipNum.compareTo(k) == 0 || endipNum.compareTo(k) == 1) {
                M = mid;
                if (mid == 0) {
                    break;
                }
                high = mid - 1;
            } else
                low = mid + 1;
        }
        return M;
    }

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

    }

    public static BigInteger stringToBigInt(String ipInString) {
        ipInString = ipInString.replace(" ", "");
        byte[] bytes = ipv6ToBytes(ipInString);
        return new BigInteger(bytes);
    }

    public static byte[] ipv6ToBytes(String ipv6) {
        try {
            // 去除可能的区域索引(如fe80::1%eth0 -> fe80::1)
            String pureIpv6 = ipv6.split("%")[0];

            // 使用InetAddress解析
            InetAddress inetAddress = InetAddress.getByName(pureIpv6);

            if (!(inetAddress instanceof Inet6Address)) {
                throw new IllegalArgumentException("Not an IPv6 address: " + ipv6);
            }

            // 直接返回16字节的地址
            return inetAddress.getAddress();

        } catch (UnknownHostException e) {
            throw new IllegalArgumentException("Invalid IPv6 address: " + ipv6, e);
        }
    }

    public static void main(String[] args) throws IOException {
        Ip ip = Ip.getInstance("D:\\databases\\ipv6_city.dat");
        System.out.println(ip.get("240e:437:cb70:1650:5428:792c:bf57:932d%0"));

    }

}

Last updated