import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; /**
* 纯真ip查询主程序
* QQWry.Dat保存在当前目录
* @author _hhh_
* @version 0.1, 04/23/08
*/
public class IpAddress { //数据库地址
private String dataPath = "QQWry.dat";
//随机文件访问类
private RandomAccessFile ipFile = null;
//单一模式实例
private static IpAddress instance = new IpAddress();
//ip开始结束位置
private long ipBegin=0L;
private long ipEnd=0L;
//ip总数
private long ipSum=0L;
//国家,地区
private String country="";
private String area=""; // 一些固定常量,比如记录长度等等
private static final int RECORD_LENGTH = 7;
private static final byte AREA_FOLLOWED = 0x01;
private static final byte NO_AREA = 0x02; /*
* 私有构造函数
*/
private IpAddress() {
try {
ipFile = new RandomAccessFile(new File(dataPath).getAbsolutePath(), "r");
} catch (FileNotFoundException e) {
System.out.println("IP地址信息文件没有找到,IP显示功能将无法使用");
e.printStackTrace();
}
if(ipFile != null) {
try {
ipBegin = byteArrayToLong(readBytes(0,4));
ipEnd = byteArrayToLong(readBytes(4,4));
if(ipBegin == -1 || ipEnd == -1) {
ipFile.close();
ipFile = null;
}
} catch (IOException e) {
System.out.println("IP地址信息文件格式有错误,IP显示功能将无法使用");
e.printStackTrace();
}
}
ipSum = (ipEnd-ipBegin)/RECORD_LENGTH+1;
} /**
* 在指定位置读取一定数目的字节
* @param offset 位置
* @param num 多少个字节
* @return ret
*/
private byte[] readBytes(long offset, int num) {
byte[] ret = new byte[num];
try {
ipFile.seek(offset); for(int i=0; i != num; i++) {
ret[i] = ipFile.readByte();
}
return ret;
} catch (IOException e) {
e.printStackTrace();
System.out.println("读取文件失败_readBytes");
return ret;
}
} /**
* 当前位置读取一定数目的字节
* @param num 多少个字节
* @return ret
*/
private byte[] readBytes(int num) {
byte[] ret = new byte[num];
try {
for(int i=0; i != num; i++) {
ret[i] = ipFile.readByte();
}
return ret;
} catch (IOException e) {
System.out.println("读取文件失败_readBytes");
return ret;
}
} /**
* 对little-endian字节序进行了转换
* byte[]转换为long
* @param b
* @return ret
*/
private long byteArrayToLong(byte[] b) {
long ret = 0;
for(int i=0; i<b.length; i++) {
ret |= ( b[i] << (0x8*i) & (0xFF * (long)(Math.pow(0x100,i))) );
}
return ret;
} /**
* 对little-endian字节序进行了转换
* @param ip ip的字节数组形式
* @return ip的字符串形式
*/
private String byteArrayToStringIp(byte[] ip) {
StringBuffer sb = new StringBuffer();
for(int i=ip.length-1; i>=0; i--) {
sb.append(ip[i] & 0xFF);
sb.append(".");
}
sb.deleteCharAt(sb.length()-1);
return sb.toString();
} /**
* 把ip字符串转换为long型
* @param ip
* @return long
*/
private long StingIpToLong(String ip) {
String[] arr = ip.split("\\.");
return (Long.valueOf(arr[0])*0x1000000 +
Long.valueOf(arr[1])*0x10000 +
Long.valueOf(arr[2])*0x100 +
Long.valueOf(arr[3]));
} /**
* 搜索ip,二分法
* @param String ip字符串0.0.0.0到255.255.255.255
* @return long ip所在位置
*/
public long seekIp(String ip) {
long tmp = StingIpToLong(ip);
long i=0;
long j=ipSum;
long m = 0;
long lm=0L;
while(i<j) {
m = (i+j)/2;
lm = m*RECORD_LENGTH + ipBegin;
if( tmp == byteArrayToLong(readBytes(lm, 4))){
return byteArrayToLong(readBytes(3));
}else if(j==(i+1)) {
return byteArrayToLong(readBytes(3));
}else if( tmp > byteArrayToLong(readBytes(lm, 4))){
i = m;
}else/* if( tmp < byteArrayToLong(readBytes(lm, 4)))*/{
j = m;
}
}
System.out.println("没有找到ip");
return -1L;
}
private String readArea(long offset) throws IOException {
ipFile.seek(offset);
byte b = ipFile.readByte();
if(b == 0x01 || b == 0x02) {
long areaOffset =byteArrayToLong(readBytes(offset+1,3));
// if(areaOffset == 0)
// return "未知";
// else
return readString(areaOffset);
} else
return readString(offset);
}
/**
* 通过ip位置获取国家地区,
* 参照纯真ip数据库结构
* @param offset
* @return 国家+地区
*/
private String seekCountryArea(long offset) {
try {
ipFile.seek(offset + 4);
byte b = ipFile.readByte();
if(b == AREA_FOLLOWED)
{
long countryOffset = byteArrayToLong(readBytes(3));
ipFile.seek(countryOffset);
b = ipFile.readByte();
if(b == NO_AREA) {
country = readString(byteArrayToLong(readBytes(3)));
ipFile.seek(countryOffset + 4);
} else
country = readString(countryOffset);
//area = readArea(ipFile.getFilePointer());
} else if(b == NO_AREA) {
country = readString(byteArrayToLong(readBytes(3)));
// area = readArea(offset + 8);
} else {
country = readString(ipFile.getFilePointer() - 1);
//area = readArea(ipFile.getFilePointer());
}
return readText(country,"省(.+?)市");//+" "+area;
} catch (IOException e) {
return null;
}
} /**
* 正则表达式解析数据
* @param result
* @identifier
* @return
*/
public static String readText(String result, String identifier) {
Pattern shopNumberPattern = Pattern.compile(identifier);
Matcher shopNamMatcher = shopNumberPattern.matcher(result);
if (shopNamMatcher.find())
return shopNamMatcher.group(1);
return "";
} /**
* 从offset偏移处读取一个以0结束的字符串
* @param offset
* @return ret 读取的字符串,出错返回空字符串
*/
private String readString(long offset){
try {
ipFile.seek(offset);
byte[] b = new byte[128];
int i;
for(i=0; (b.length != i) && ((b[i]=ipFile.readByte()) != 0); i++);
String ret = new String(b, 0 , i/*, "GBK"*/);
ret = ret.trim();
return (ret.equals("") ||
ret.indexOf("CZ88.NET") != -1 )?"未知":ret;
} catch (IOException e) {
System.out.println("读取文件失败_readString");
}
return "";
} /**
* 包含字符串的ip记录
* @param addr 地址
* @return IpRecord ip记录
*/ public ArrayList<IpRecord> stringToIp(String addr) {
ArrayList<IpRecord> ret = new ArrayList<IpRecord>();
try{
FileChannel fc = ipFile.getChannel();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, ipFile.length());
mbb.order(ByteOrder.LITTLE_ENDIAN);
//上面3代码未使用,内存映射文件功能未写 for(long i = ipBegin+4; i != ipEnd+4; i += RECORD_LENGTH) {
String sca = seekCountryArea(byteArrayToLong(readBytes(i, 3)));
if(sca.indexOf(addr) != -1) {
IpRecord rec = new IpRecord();
rec.address = sca;
rec.beginIp= byteArrayToStringIp(readBytes(i-4,4));
rec.endIp= byteArrayToStringIp(readBytes(i+3,4));
ret.add(rec);
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
return ret;
} /**
* 封装ip记录,包括开始ip,结束ip和地址
*/
private class IpRecord {
public String beginIp;
public String endIp;
public String address; public IpRecord() {
beginIp = endIp = address = "";
} public String toString() {
return beginIp + " - " + endIp + " " + address;
}
} /**
* @return 单一实例
*/
public static IpAddress getInstance() {
return instance;
} /**
* @param ip
* @return ret
*/
public String IpStringToAddress(String ip) {
//这里要添加ip格式判断
//public boolean isIP(Strin ip)
long ipOffset = seekIp(ip);
String ret = seekCountryArea(ipOffset);
return ret;
} /**
* @return IpSum
*/
public long getIpSum() {
return ipSum;
} public static void main(String[] args) throws UnknownHostException {
IpAddress ipAddr = IpAddress.getInstance();
//ip总数
long l = ipAddr.getIpSum();
System.out.println(l);
//纯真ip数据更新时间
String str = ipAddr.IpStringToAddress("255.255.255.0");
System.out.println(str); //测试
str = ipAddr.IpStringToAddress("222.88.59.214");
System.out.println(str);
str = ipAddr.IpStringToAddress("222.248.70.78");
System.out.println(str);
str = ipAddr.IpStringToAddress("188.1.255.255");
System.out.println(str);
str = ipAddr.IpStringToAddress("220.168.59.166");
System.out.println(str);
str = ipAddr.IpStringToAddress("221.10.61.90");
System.out.println(str);
InetAddress inet = InetAddress.getLocalHost();
System.out.println("本机的ip=" + inet.getHostAddress());
/* java.net.InetAddress addr = null;
try{
addr = java.net.InetAddress.getLocalHost();
}catch(java.net.UnknownHostException e){
e.printStackTrace();
}
String ip=addr.getHostAddress().toString();//获得本机IP
System.out.print(ip);
String address=addr.getHostName().toString();//获得本机名称
System.out.print(address);
str = ipAddr.IpStringToAddress(ip);
System.out.println(str);*/ ArrayList<IpRecord> al = ipAddr.stringToIp("网吧");
Iterator it = al.iterator(); File f = new File("ipdata.txt");
try{
if(!f.exists()) {
f.createNewFile();
}
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(f, true)
)
);
int i=0;
while(it.hasNext()) {
out.write(it.next().toString());
out.newLine();
i++;
}
out.write(new Date().toString());
out.write("总共搜索到 "+i);
out.close();
}catch(IOException e){
e.printStackTrace();
} }
}

自己在网上在去下载个qqwry.dat放到根目录下就好

java通过IP地址获取物理位置的更多相关文章

  1. Java根据ip地址获取Mac地址,Java获取Mac地址

    Java根据ip地址获取Mac地址,Java获取Mac地址 >>>>>>>>>>>>>>>>>&g ...

  2. java根据ip地址获取详细地域信息的方法

    通过淘宝IP地址库获取IP位置(也可以使用新浪的) 请求接口(GET):http://ip.taobao.com/service/getIpInfo.php?ip=[ip地址字串] 响应信息:(jso ...

  3. python绝技 — 使用PyGeoIP关联IP地址和物理位置

    准备工作 要关联IP与物理位置,我们需要有一个包含这样对应关系的数据库. 我们可以使用开源数据库GeoLiteCity,它能够较为准确地把IP地址与所在城市关联起来 下载地址:http://dev.m ...

  4. Java根据IP地址获取MAC地址

    先使用ping -n  2 10.0.0.1 命令,如果返回的结果中含有TTL字符,证明ping 10.0.0.1是能ping通的,即可达的.如果在Linux机器上请使用 ping -c 2 10.0 ...

  5. 运用百度开放平台接口根据ip地址获取位置

    使用百度开放平台接口根据ip地址获取位置 今天无意间发现在百度开放平台接口,就把一段代码拿了下来,有需要的可以试试看:http://opendata.baidu.com/api.php?query=5 ...

  6. 腾讯新浪通过IP地址获取当前地理位置(省份)的接口

    腾讯新浪通过IP地址获取当前地理位置(省份)的接口  腾讯的接口是 ,返回数组 http://fw.qq.com/ipaddress 返回值 var IPData = new Array(" ...

  7. Java实现Internet地址获取

    Java实现Internet地址获取 代码内容 输入域名输出IPV4地址 输入IP地址输出域名 支持命令行输入 支持交互式输入 代码实现 /* nslookup.java */ import java ...

  8. PHP:根据IP地址获取所在城市

    文件目录: ipLocation -----qqwry ----------QQWry.Dat -----ipCity.class.php ipCity.class.php文件代码: <?php ...

  9. 转:为什么根据IP地址查询物理所在地,而不是mac地址?

    来自 https://mp.weixin.qq.com/s/aOZQGMnMI2nkX4-qcJL4WQ 读者 不是说mac地址是计算机网卡唯一的地址吗?这样不是可以直接定位到某一台机器吗?为什么要用 ...

随机推荐

  1. Python基础之逻辑运算

    逻辑运算 概念: 优先级() > not > and > or print(2 > 1 and 1 < 4 or 2 < 3 and 9 > 6 or 2 & ...

  2. js导出excel:前端当前数据的导出

    网上找的库文件,同样做了修改.在导出的时候,有时候数据第一列和最后一列可能是复选框和操作按钮,这个是我们不需要的,加了这个的过滤 //table2excel.js /* * jQuery table2 ...

  3. 前端框架(kraken、Express、Node、MVC)

    You know my loneliness is only kept for you, my sweet songs are only sang for you. 前端框架相关知识记录. krake ...

  4. AngularJS——第4章 数据绑定

    第4章 数据绑定 AngularJS是以数据做为驱动的MVC框架,所有模型(Model)里的数据经由控制器(Controller)展示到视图(View)中. 所谓数据绑定指的就是将模型(Model)中 ...

  5. git--(3)分支 合并

    git branch test //新建分支 git branch //列出分支 git branch -r //列出远程分支 git branch -m | -M oldbranch newbran ...

  6. springboot 日志1

    技术交流群: 816227112 Spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持,如:Java Util Logging,Log4J,  ...

  7. rbac之 权限粒度控制到按钮级别

    rbac之 权限粒度控制到按钮级别:  这里的意思就是 如果当前用户,没有这个权限. 那么这个相对应的这个按钮的权限, 就不应该展示.看都不能给看到. 思路: 为每一个权限,设置一个别名.  这里是这 ...

  8. Django ORM那些相关操作zi

    Django ORM那些相关操作   一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs) ...

  9. 关于Vector,map等迭代器问题

    vector.erase(it):后,it自动++,一定要弄清楚,删除成功后it指向删除的下一个地址. 对于map.erase(it),返回值为NULL,而Vector是返回itorator

  10. iOS.Animation.CAMediaTiming

    CAMediaTiming Protocol CALayre 和 CAAnimation 实现了CAMediaTiming 接口. CAMediaTiming 定义了8个属性. speed属性: Co ...