【文件属性】:
文件名称:ip地址库 很全的库
文件大小:9.13MB
文件格式:DAT
更新时间:2023-02-28 07:25:56
ip地址资源
ip地址资源
/**
*
*/
package common.tools.ip.ipSeeker;
import common.tools.ip.Utils;
import common.webBase.base.util.Log4jUtil;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* LumaQQ - Java QQ Client
*
* Copyright (C) 2004 luma < stubma@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* 用来读取QQwry.dat文件,以根据ip获得好友位置,QQwry.dat的格式是 一. 文件头,共8字节 1. 第一个起始IP的绝对偏移, 4字节 2.
* 最后一个起始IP的绝对偏移, 4字节 二. "结束地址/国家/区域"记录区 四字节ip地址后跟的每一条记录分成两个部分 1. 国家记录 2. 地区记录
* 但是地区记录是不一定有的。而且国家记录和地区记录都有两种形式 1. 以0结束的字符串 2. 4个字节,一个字节可能为0x1或0x2 a.
* 为0x1时,表示在绝对偏移后还跟着一个区域的记录,注意是绝对偏移之后,而不是这四个字节之后 b. 为0x2时,表示在绝对偏移后没有区域记录
* 不管为0x1还是0x2,后三个字节都是实际国家名的文件内绝对偏移
* 如果是地区记录,0x1和0x2的含义不明,但是如果出现这两个字节,也肯定是跟着3个字节偏移,如果不是 则为0结尾字符串 三.
* "起始地址/结束地址偏移"记录区 1. 每条记录7字节,按照起始地址从小到大排列 a. 起始IP地址,4字节 b. 结束ip地址的绝对偏移,3字节
*
* 注意,这个文件里的ip地址和所有的偏移量均采用little-endian格式,而java是采用 big-endian格式的,要注意转换
*/
public class IPSeeker {
/**
* 用来封装ip相关信息,目前只有两个字段,ip所在的国家和地区
*/
private class IPLocation {
public String country;
public String area;
public IPLocation() {
country = area = "";
}
public IPLocation getCopy() {
IPLocation ret = new IPLocation();
ret.country = country;
ret.area = area;
return ret;
}
}
// private static final String IP_FILE =
// IPSeeker.class.getResource("/qqwryIP.dat").toString().substring(5);
// private static final String IP_FILE;
// 一些固定常量,比如记录长度等等
private static final int IP_RECORD_LENGTH = 7;
private static final byte AREA_FOLLOWED = 0x01;
private static final byte NO_AREA = 0x2;
// 用来做为cache,查询一个ip时首先查看cache,以减少不必要的重复查找
private Hashtable ipCache;
// 随机文件访问类
private RandomAccessFile ipFile;
// 内存映射文件
private MappedByteBuffer mbb;
// 单一模式实例
private static volatile IPSeeker instance = null;
// 起始地区的开始和结束的绝对偏移
private long ipBegin, ipEnd;
// 为提高效率而采用的临时变量
private IPLocation loc;
private byte[] buf;
private byte[] b4;
private byte[] b3;
private String province = null;
private String city = null;
private String county = null;
/**
* 私有构造函数
*/
private IPSeeker(String IP_FILE) {
ipCache = new Hashtable();
loc = new IPLocation();
buf = new byte[100];
b4 = new byte[4];
b3 = new byte[3];
try {
ipFile = new RandomAccessFile(IP_FILE, "r");
// ipFile = IPSeeker.class.getResource("/qqwryIP.dat");
} catch (FileNotFoundException e) {
// Log4jUtil.info(IPSeeker.class.getResource("/qqwryIP.dat").toString());
// Log4jUtil.info(IP_FILE);
// Log4jUtil.info("IP地址信息文件没有找到,IP显示功能将无法使用");
// e.printStackTrace();
ipFile = null;
}
// 如果打开文件成功,读取文件头信息
if (ipFile != null) {
try {
ipBegin = readLong4(0);
ipEnd = readLong4(4);
if (ipBegin == -1 || ipEnd == -1) {
ipFile.close();
ipFile = null;
}
} catch (IOException e) {
Log4jUtil.error("IP地址信息文件格式有错误,IP显示功能将无法使用", e);
ipFile = null;
}
}
}
/**
* @return 单一实例
*/
public static IPSeeker getInstance(String wryIPURL) {
synchronized (wryIPURL) {
if (null == instance) {
instance = new IPSeeker(wryIPURL);
}
return instance;
}
}
/**
* 给定一个地点的不完全名字,得到一系列包含s子串的IP范围记录
*
* @param s
* 地点子串
* @return 包含IPEntry类型的List
*/
public List getIPEntriesDebug(String s) {
List ret = new ArrayList();
long endOffset = ipEnd + 4;
for (long offset = ipBegin + 4; offset <= endOffset; offset += IP_RECORD_LENGTH) {
// 读取结束IP偏移
long temp = readLong3(offset);
// 如果temp不等于-1,读取IP的地点信息
if (temp != -1) {
IPLocation loc = getIPLocation(temp);
// 判断是否这个地点里面包含了s子串,如果包含了,添加这个记录到List中,如果没有,继续
if (loc.country.indexOf(s) != -1 || loc.area.indexOf(s) != -1) {
IPEntry entry = new IPEntry();
entry.country = loc.country;
entry.area = loc.area;
// 得到起始IP
readIP(offset - 4, b4);
entry.beginIp = Utils.getIpStringFromBytes(b4);
// 得到结束IP
readIP(temp, b4);
entry.endIp = Utils.getIpStringFromBytes(b4);
// 添加该记录
ret.add(entry);
}
}
}
return ret;
}
/**
* 给定一个地点的不完全名字,得到一系列包含s子串的IP范围记录
*
* @param s
* 地点子串
* @return 包含IPEntr