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. spark快速开发之scala基础之1 数据类型与容器

    写在前面 面向java开发者.实际上,具有java基础学习scala是很容易.java也可以开发spark,并不比scala开发的spark程序慢.但学习scala可有助于更快更好的理解spark.比 ...

  2. VM虚拟机的配置文件(.vmx)损坏

    为了禁用时间同步,使用sublime修改vmx文件 文件第一行为.encoding = "GBK" 修改完毕,无法打开虚拟机,报 VM虚拟机的配置文件(.vmx)损坏错误 因为su ...

  3. poj3104(二分)

    题目链接:http://poj.org/problem?id=3104 题意:有n件衣服,每一件含有a[i]单位的水,每分钟衣服可以自然蒸发1单位的水,也可以在烘干器上每分钟烘干k单位的水,问将所有衣 ...

  4. CUDA 编程的基本模式

    reproduced from: http://www.cnblogs.com/muchen/p/6306747.html 前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式 ...

  5. Vue之组件

    Vue之全局组件 全局组件可以被任何局部组件调用 <div id="app"> <!--这里是组件的使用--> <global-component&g ...

  6. Unity3D研究院之设置自动旋转屏幕默认旋转方向

    如下图所示,在处理屏幕默认旋转方向的时候可以在这里进行选择,上下左右一共是4个方向. 策划的需求是游戏采用横屏,但是要求支持两个方向自动旋转,如下图所示,我的设置是这样的. Default Orien ...

  7. 关于后台执行JS代码总结

    方法一.FineUI的 pagecontext对象 string js="functionName();"; PageContext.RegisterStartUpScript(j ...

  8. 微信公众号开发(5)---使用开源组件开发公众号OAuth2.0网页授权授权登录

    搞清微信公众号授权登录的步骤步骤,我们的开发就完成了一大步 献上github 地址: https://github.com/Wechat-Group/weixin-java-tools/wiki/MP ...

  9. C++ 计算直线的交点数(动态规划)

    问题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1466 Problem Description 平面上有n条直线,且无三线共点,问这些直线能有多少种不同 ...

  10. golang 创建一个简单的资源池,重用资源,减少GC负担

    package main; import ( "sync" "errors" "fmt" ) //代码参考<Go语言实战>中第7 ...