论坛首页 入门技术论坛

IP库的查询

浏览 4226 次
锁定老帖子 主题:IP库的查询
该帖已经被评为新手帖
作者 正文
   发表时间:2008-04-02  
做了一段时间的数据统计功能,无论是apache,还是tomcat,在记录日志的过程中都有IP被记录,目前大多数软件的后台都要求统计一下,数据的来源是从哪些城市过来的,所以要用到IP库。以前一直以为这个东西一定是购买的,后来在网上终于找到了免费的,还是还位仁兄特意写了java的代码用来参考!在些表示感谢!
转载地址:
http://www.blogjava.net/alvin/archive/2007/08/23/141139.html

import java.io.*;

public class QQWry {
private String DbPath = "D:\\Downloads\\IPLook\\QQWry.Dat" + ""; // 纯真IP数据库地址

private String Country, LocalStr;

private long IPN;

private int RecordCount, CountryFlag;

private long RangE, RangB, OffSet, StartIP, EndIP, FirstStartIP,
LastStartIP, EndIPOff;

private RandomAccessFile fis;

private byte[] buff;

private long B2L(byte[] b) {
long ret = 0;
for (int i = 0; i < b.length; i++) {
long t = 1L;
for (int j = 0; j < i; j++)
t = t * 256L;
ret += ((b[i] < 0) ? 256 + b[i] : b[i]) * t;
}
return ret;
}

private long ipToInt(String ip) {
String[] arr = ip.split("\\.");
long ret = 0;
for (int i = 0; i < arr.length; i++) {
long l = 1;
for (int j = 0; j < i; j++)
l *= 256;
try {
ret += Long.parseLong(arr[arr.length - i - 1]) * l;
} catch (Exception e) {
ret += 0;
}
}
return ret;
}

public void seek(String ip) throws Exception {
this.IPN = ipToInt(ip);
fis = new RandomAccessFile(this.DbPath, "r");
buff = new byte[4];
fis.seek(0);
fis.read(buff);
FirstStartIP = this.B2L(buff);
fis.read(buff);
LastStartIP = this.B2L(buff);
RecordCount = (int) ((LastStartIP - FirstStartIP) / 7);
if (RecordCount <= 1) {
LocalStr = Country = "未知";
throw new Exception();
}

RangB = 0;
RangE = RecordCount;
long RecNo;

do {
RecNo = (RangB + RangE) / 2;
getStartIP(RecNo);
if (IPN == StartIP) {
RangB = RecNo;
break;
}
if (IPN > StartIP)
RangB = RecNo;
else
RangE = RecNo;
} while (RangB < RangE - 1);

getStartIP(RangB);
getEndIP();
getCountry(IPN);

fis.close();
}

private String getFlagStr(long OffSet) throws IOException {
int flag = 0;
do {
fis.seek(OffSet);
buff = new byte[1];
fis.read(buff);
flag = (buff[0] < 0) ? 256 + buff[0] : buff[0];
if (flag == 1 || flag == 2) {
buff = new byte[3];
fis.read(buff);
if (flag == 2) {
CountryFlag = 2;
EndIPOff = OffSet - 4;
}
OffSet = this.B2L(buff);
} else
break;
} while (true);

if (OffSet < 12) {
return "";
} else {
fis.seek(OffSet);
return getStr();
}
}

private String getStr() throws IOException {
long l = fis.length();
ByteArrayOutputStream byteout = new ByteArrayOutputStream();
byte c = fis.readByte();
do {
byteout.write(c);
c = fis.readByte();
} while (c != 0 && fis.getFilePointer() < l);
return byteout.toString();
}

private void getCountry(long ip) throws IOException {
if (CountryFlag == 1 || CountryFlag == 2) {
Country = getFlagStr(EndIPOff + 4);
if (CountryFlag == 1) {
LocalStr = getFlagStr(fis.getFilePointer());
if (IPN >= ipToInt("255.255.255.0")
&& IPN <= ipToInt("255.255.255.255")) {
LocalStr = getFlagStr(EndIPOff + 21);
Country = getFlagStr(EndIPOff + 12);
}
} else {
LocalStr = getFlagStr(EndIPOff +;
}
} else {
Country = getFlagStr(EndIPOff + 4);
LocalStr = getFlagStr(fis.getFilePointer());
}
}

private long getEndIP() throws IOException {
fis.seek(EndIPOff);
buff = new byte[4];
fis.read(buff);
EndIP = this.B2L(buff);
buff = new byte[1];
fis.read(buff);
CountryFlag = (buff[0] < 0) ? 256 + buff[0] : buff[0];
return EndIP;
}

private long getStartIP(long RecNo) throws IOException {
OffSet = FirstStartIP + RecNo * 7;
fis.seek(OffSet);
buff = new byte[4];
fis.read(buff);
StartIP = this.B2L(buff);
buff = new byte[3];
fis.read(buff);
EndIPOff = this.B2L(buff);
return StartIP;
}

public String getLocal() {
return this.LocalStr;
}

public String getCountry() {
return this.Country;
}

public void setPath(String path) {
this.DbPath = path;
}

public static void main(String[] args) throws Exception {
QQWry w = new QQWry();
// w.setPath(new File("QQWry2.Dat").getAbsolutePath());
w.seek("219.232.233.103");
System.out.println(w.getCountry() + " " + w.getLocal());
}

}
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics