java 通过 ip 纯真库 获取国家
时间: 2024-03-12 10:47:46 浏览: 220
纯真 IP 库是一个比较常用的 IP 归属地查询库,可以在 Java 中通过读取纯真 IP 库的二进制文件来获取 IP 地址的国家和地区信息。
以下是一个使用纯真 IP 库查询 IP 地址归属地的示例代码:
```java
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class IP2CountryExample {
public static void main(String[] args) {
String ip = "127.0.0.1";
try {
File file = new File("C:\\Program Files (x86)\\QQBrowser\\QQBrowser.exe");
RandomAccessFile raf = new RandomAccessFile(file, "r");
// 读取索引区头信息
int indexStart = raf.readIntLE();
int indexEnd = raf.readIntLE();
int indexCount = (indexEnd - indexStart) / 7 + 1;
// 二分查找 IP 地址所在的索引
long ipLong = ipToLong(ip);
int low = 0, high = indexCount - 1;
while (low <= high) {
int mid = (low + high) / 2;
long midIp = readIp(raf, indexStart + mid * 7);
if (ipLong < midIp) {
high = mid - 1;
} else if (ipLong > midIp) {
low = mid + 1;
} else { // 找到了对应的索引
int countryOffset = readInt24(raf);
raf.seek(countryOffset);
byte countryFlag = raf.readByte();
if (countryFlag == 1) { // 表示国家信息被重定向到其他位置
int redirectOffset = readInt24(raf);
raf.seek(redirectOffset);
}
String country = raf.readLine();
System.out.println("Country: " + country);
break;
}
}
raf.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
// 把 IP 地址转换成 long 类型
private static long ipToLong(String ip) {
String[] ips = ip.split("\\.");
long result = 0;
for (int i = 0; i < ips.length; i++) {
result = result * 256 + Integer.parseInt(ips[i]);
}
return result;
}
// 从文件指定位置读取 3 字节无符号整数
private static int readInt24(RandomAccessFile raf) throws IOException {
byte[] bytes = new byte[3];
raf.readFully(bytes);
return ((bytes[2] & 0xFF) << 16) | ((bytes[1] & 0xFF) << 8) | (bytes[0] & 0xFF);
}
// 从文件指定位置读取 4 字节无符号整数
private static long readInt32(RandomAccessFile raf, long pos) throws IOException {
raf.seek(pos);
int ch1 = raf.read();
int ch2 = raf.read();
int ch3 = raf.read();
int ch4 = raf.read();
if ((ch1 | ch2 | ch3 | ch4) < 0) {
throw new IOException("EOF");
}
return ((long) ch1 << 24) + ((long) ch2 << 16) + ((long) ch3 << 8) + (ch4 & 0xFF);
}
// 从文件指定位置读取 4 字节有符号整数
private static int readInt32LE(RandomAccessFile raf, long pos) throws IOException {
raf.seek(pos);
int ch1 = raf.read();
int ch2 = raf.read();
int ch3 = raf.read();
int ch4 = raf.read();
if ((ch1 | ch2 | ch3 | ch4) < 0) {
throw new IOException("EOF");
}
return (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1;
}
// 从文件指定位置读取 4 字节无符号整数
private static long readUInt32LE(RandomAccessFile raf, long pos) throws IOException {
return readInt32LE(raf, pos) & 0xFFFFFFFFL;
}
// 从文件指定位置读取 IP 地址
private static long readIp(RandomAccessFile raf, long pos) throws IOException {
return readUInt32LE(raf, pos);
}
}
```
在这个示例中,我们使用了纯真 IP 库的二进制文件,通过读取索引区头信息和 IP 地址所在的索引,然后读取对应的国家信息来获取 IP 地址的归属地信息。需要注意的是,这个示例代码仅仅是一个演示,实际使用中需要根据具体的纯真 IP 库版本进行修改。
阅读全文