java通过IP地址获取物理位置
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地址获取物理位置的更多相关文章
- Java根据ip地址获取Mac地址,Java获取Mac地址
Java根据ip地址获取Mac地址,Java获取Mac地址 >>>>>>>>>>>>>>>>>&g ...
- java根据ip地址获取详细地域信息的方法
通过淘宝IP地址库获取IP位置(也可以使用新浪的) 请求接口(GET):http://ip.taobao.com/service/getIpInfo.php?ip=[ip地址字串] 响应信息:(jso ...
- python绝技 — 使用PyGeoIP关联IP地址和物理位置
准备工作 要关联IP与物理位置,我们需要有一个包含这样对应关系的数据库. 我们可以使用开源数据库GeoLiteCity,它能够较为准确地把IP地址与所在城市关联起来 下载地址:http://dev.m ...
- Java根据IP地址获取MAC地址
先使用ping -n 2 10.0.0.1 命令,如果返回的结果中含有TTL字符,证明ping 10.0.0.1是能ping通的,即可达的.如果在Linux机器上请使用 ping -c 2 10.0 ...
- 运用百度开放平台接口根据ip地址获取位置
使用百度开放平台接口根据ip地址获取位置 今天无意间发现在百度开放平台接口,就把一段代码拿了下来,有需要的可以试试看:http://opendata.baidu.com/api.php?query=5 ...
- 腾讯新浪通过IP地址获取当前地理位置(省份)的接口
腾讯新浪通过IP地址获取当前地理位置(省份)的接口 腾讯的接口是 ,返回数组 http://fw.qq.com/ipaddress 返回值 var IPData = new Array(" ...
- Java实现Internet地址获取
Java实现Internet地址获取 代码内容 输入域名输出IPV4地址 输入IP地址输出域名 支持命令行输入 支持交互式输入 代码实现 /* nslookup.java */ import java ...
- PHP:根据IP地址获取所在城市
文件目录: ipLocation -----qqwry ----------QQWry.Dat -----ipCity.class.php ipCity.class.php文件代码: <?php ...
- 转:为什么根据IP地址查询物理所在地,而不是mac地址?
来自 https://mp.weixin.qq.com/s/aOZQGMnMI2nkX4-qcJL4WQ 读者 不是说mac地址是计算机网卡唯一的地址吗?这样不是可以直接定位到某一台机器吗?为什么要用 ...
随机推荐
- linux启动jmeter(二十三),执行./jmeter.sh报错解决方法(转载)
转载自 http://www.cnblogs.com/yangxia-test 1.l-bash: ./jmeter.sh: Permission denied解决办法:jmeter.sh的执行权限改 ...
- pm2-zabbix 安装与配置
官方GITHUB路径 https://github.com/greatcare/pm2-zabbix 环境要求,zabbix-agent zabbix-sender需要安装 npm安装要求 npm i ...
- python网络爬虫《http和https协议》
一.HTTP协议 1.官方概念: HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文 ...
- UVA-10054.The Necklace(欧拉回路)解题报告
2019-02-09-21:55:23 原题链接 题目描述: 给定一串珠子的颜色对,每颗珠子的两端分别有颜色(用1 - 50 之间的数字表示,对每颗珠子的颜色无特殊要求),若两颗珠子的连接处为同种颜色 ...
- 189. Rotate Array(Array)
Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array ...
- 网页请求get方式
方法都是博客中的大神写的,谢谢各路大神. 方法一:(亲测有效) //Get请求方式 private string RequestGet(string Url) { string PageStr = s ...
- [leetcode]694. Number of Distinct Islands你究竟有几个异小岛?
Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...
- linux命令学习之:passwd
passwd命令用于设置用户的认证信息,包括用户密码.密码过期时间等.系统管理者则能用它管理系统用户的密码.只有管理者可以指定用户名称,一般用户只能变更自己的密码. 语法 passwd(选项)(参数) ...
- linux命令学习之:tar
tar命令可以为linux的文件和目录创建档案.利用tar,可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件.tar最初被用来在磁带上创建档案,现在,用户可以在 ...
- 建立SSH的信任关系
1.在Client上root用户执行ssh-keygen命令,生成建立安全信任关系的证书. Client端 # ssh-keygen -t rsa Generating public/private ...