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. Log4j2配置及使用

    Log4j2:一个日志管理工具.Log4j的升级版,需要Java6以上   一.安装log4j2依赖包 1.通过maven的pom.xml直接引入jar: log4j-api和log4j-core & ...

  2. 【C++】cout未刷新缓冲区仍会输出的问题

    众所周知,cout是一个流对象,管理一个缓冲区.当使用<<操作符输出字符串时,字符串不是直接被输出到屏幕上,而是首先被插入到该流的缓存(buffer)中.而只有当缓冲区被刷新时,字符串才会 ...

  3. web前端开发浏览器兼容性处理大全

    1.居中问题 div里的内容,IE默认为居中,而FF默认为左对齐,可以尝试增加代码margin: 0 auto; 2.高度问题 两上下排列或嵌套的div,上面的div设置高度(height),如果di ...

  4. python爬虫相关基础概念

    什么是爬虫 爬虫就是通过编写程序模拟浏览器上网,然后让其去互联网上抓取数据的过程. 哪些语言可以实现爬虫 1.php:可以实现爬虫.但是php在实现爬虫中支持多线程和多进程方面做得不好. 2.java ...

  5. PHP抽象方法、抽象类以及接口

     1.什么是抽象方法?    我们在类里面定义的没有方法提的方法就是抽象方法.所谓的没有方法体指的是,在声明的时候没有大括号以及其中的内容,而是直接在声明时在方法名后加上分号结束,另外在声明抽象方法时 ...

  6. unity3D OnTriggerEnter和OnCollisionEnter的区别

    1,测试OnTriggerEnter和OnCollisionEnter的区别 测试:如果两个物体A,B 两者都有碰撞体collider(Box Collider,Sphere Collider,Cap ...

  7. RocketMq --consumer自动实现负载均衡

    这边使用一个producer和两个consumer是实现负载均衡. 看一下代码示例 package com.alibaba.rocketmq.example.message.model; import ...

  8. am start的总结,-d参数的总结,以及python中传递内容包含中文及特殊字符&的解决方案

    一.am start的内容的整理 主要包含以下内容:am start的常规操作及参数的含义,-d 参数的含义,以及如何在APK中设置参数获取 使用命令如下:adb shell am start -n ...

  9. 【Android端ANR卡顿检测】BlockCanary检测

    一.什么是BlockCanary? 检测主线程卡顿的一个开源工具,基本展现模式等都和LeakCanary很像 二.BlockCanary的工作原理是什么? 工作原理所涉及到的底层的内容一定要理解清楚 ...

  10. 高盛昂赛 算法题先写corner case

    [方法] 字写大点,先注释框架 链表:指针走就行了,最多是两个同时一起走. 两个链表求交点 //corner case if (headA == null || headB == null) { re ...