IP定位:通过qqwry.bat IP库获取指定IP的地理位置信息

qqwry.bat 下载地址 http://download.csdn.net/detail/takeurhand/8048487

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Name IpAddress
 * @Description 根据Ip判断地理位置
 * @Attention NULL
 * @Tags 
 * @Author CaiYj
 * <br>2014-10-17
 */
public class IpAddress {

   /**
    * bat文件地址(这是一个ip库)
    */
   private String dataPath = "src/QQWry.dat";
   private RandomAccessFile ipFile = null;
   private static IpAddress instance = new IpAddress();
   private long ipBegin=0L;
   private long ipEnd=0L;
   private long ipSum=0L;
   private String country="";
   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) {  
    	   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) {
               e.printStackTrace();
           }
       }
       ipSum = (ipEnd-ipBegin)/RECORD_LENGTH+1;
   }
   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();
           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) {
           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;
   }

   /**
    * @Name 
    * @Description 把ip字符串转换为long型
    * @Attention NULL
    * @ReturnType long NULL
    * @Tags @param ip
    * @Tags @return
    * @Author CaiYj
    * <br>2014-10-17
    */
   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]));   
   }
   /**
    * @Name 
    * @Description 搜索ip
    * @Attention NULL
    * @ReturnType long NULL
    * @Tags @param ip
    * @Tags @return
    * @Author CaiYj
    * <br>2014-10-17
    */
   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;
           }
       }
       return -1L;
   }
   /**
    * @Name 
    * @Description seekCountryArea di
    * @Attention NULL
    * @ReturnType String NULL
    * @Tags @param offset
    * @Tags @return
    * @Author CaiYj
    * <br>2014-10-17
    */
   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;
       }
   }
   
  /**
   * @Name 
   * @Description readText
   * @Attention NULL
   * @ReturnType String NULL
   * @Tags @param result
   * @Tags @param identifier
   * @Tags @return
   * @Author CaiYj
   * <br>2014-10-17
   */
   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 "";   
   } 

   /**
    * @Name 
    * @Description 从offset偏移处读取一个以0结束的字符串
    * @Attention NULL
    * @ReturnType String NULL
    * @Tags @param offset
    * @Tags @return
    * @Author CaiYj
    * <br>2014-10-17
    */
   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 "";
   }

   /**
    * @Name IpRecord
    * @Description 封装ip记录,包括开始ip,结束ip和地址
    * @Attention NULL
    * @Tags 
    * @Author CaiYj
    * <br>2014-10-17
    */
   @SuppressWarnings("unused")
   private class IpRecord {
       public String beginIp;
       public String endIp;
       public String address;

       public IpRecord() {
           beginIp = endIp = address = "";   
       }

       public String toString() {
           return beginIp + " - " + endIp + " " + address;
       }
   }

   /**
    * @Name 
    * @Description Singleton
    * @Attention NULL
    * @ReturnType IpAddress NULL
    * @Tags @return
    * @Author CaiYj
    * <br>2014-10-17
    */
   public static IpAddress getInstance() {
       return instance;
   }
   /**
    * @Name 
    * @Description NULL
    * @Attention NULL
    * @ReturnType String NULL
    * @Tags @param ip
    * @Tags @return
    * @Author CaiYj
    * <br>2014-10-17
    */
   public String IpStringToAddress(String ip) {
       long ipOffset = seekIp(ip);
       String ret = seekCountryArea(ipOffset);
       return ret;
   }

  /**
   * @Name 
   * @Description NULL
   * @Attention NULL
   * @ReturnType long ipSum
   * @Tags @return
   * @Author CaiYj
   * <br>2014-10-17
   */
   public long getIpSum() {
       return ipSum;
   }

   public static void main(String[] args) throws UnknownHostException {
       IpAddress ipAddr = IpAddress.getInstance();
//       	/**
//       	 * ip总数 long
//       	 */
//       long l = ipAddr.getIpSum();
//       System.out.println(l);
       String str = ipAddr.IpStringToAddress("255.255.255.0");
       System.out.println("255.255.255.0 "+str);
       str = ipAddr.IpStringToAddress("113.235.124.128");
       System.out.println("113.235.124.128 "+str);
       str = ipAddr.IpStringToAddress("192.168.0.174");
       System.out.println("192.168.0.174"+str);
       InetAddress inet = InetAddress.getLocalHost(); 
       System.out.println("本地ip" + inet.getHostAddress()); 
   }   
} 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
lib-qqwry是一个高效查询纯真 IP (qqwry.dat)的模块。它是用 NodeJS 解析纯真 IP (QQwry.dat) ,支持 IP 段查询。为更好的字符转化效率,未使用iconv模块,直接使用gbk编码表文件。经过不断优化,相同环境下,单次查询速度从最初的0.6毫秒提升到现在的0.004毫秒。实现的功能1.通过IP地址或有效的IP数值,搜索IP地址对应的地理位置信息。2.搜索一个IP段的地理位置信息。3.IP地址与数值的互转。npm安装npm install lib-qqwry调用方法var qqwry = require('lib-qqwry').info(); //调用并初始化,普通机器初始需要70毫秒左右; var ipL = qqwry.searchIP("202.103.102.10"); //查询IP信息 var ipLA = qqwry.searchIPScope("0.0.0.0","1.0.0.0");  //查询IP信息API标明的"静态方法"可以值接使用,无需初始化.初使化操作会将GBK编码表,IP加载到内存中,以提高后续的查询效率,大概占用12M左右的内存.info(dataPath) IP初始化dataPath : IP路径,可选; //默认路径为data文件夹中(__dirname "/data/qqwry.dat");callback : 回调函数 //可在此时调用查询函数infoAsync(dataPath,callback) IP初始化的异步方法info()的异步方法; 初始化需要70毫秒,以及占用9MB左右的内存,项目资源紧张可以异步初始化。//你可以这样 qqwry.info(); var ipL = qqwry.searchIP("202.103.102.10"); //也可以这样初始化,推荐; qqwry.infoAsync(function(){     var ipL = qqwry.searchIP("202.103.102.10"); });unInfo() 释放初始化后占用的资源info()的逆方法searchIP(IP) 单个IP查询IP : IP地址/IP数值 反回一个JSON对像;> qqwry.searchIP("255.255.255.255"); { ip: '255.255.255.255',   Country: '纯真网络',   Area: '2013年6月10日IP数据' }searchIPScope(beginIP,endIP) IP段查询beginIP : 启始IPendIP : 结束IP反回一个JSON对像数组;> qqwry.searchIPScope("0.0.0.0","1.0.0.0"); [ { begIP: '0.0.0.0',     endIP: '0.255.255.255',     Country: 'IANA保留地址',     Area: ' CZ88.NET' },   { begIP: '1.0.0.0',     endIP: '1.0.0.255',     Country: '澳大利亚',     Area: ' CZ88.NET' } ]searchIPScopeAsync(beginIP,endIP,callback) IP段查询的异步方法searchIPScope() 的异步方法,查询结果会以第一个参数的形式传给回调函数;DBUG(Bool) 调试模式开关,默认未启用DUBG模式会在控制台输出查询的关键信息,方便定位错误;var qqwry = require('lib-qqwry').DBUG().info(); //开启调试模式并初始化 qqrry.DBUG(false); //关闭调试模式;ipToInt(IP) IP地址转数值(静态方法)> qqwry.ipToInt("255.255.255.255") 4294967295intToIP(INT) 数值转IP地址(静态方法)> qqwry.intToIP(4294967295) '255.255.255.255'ipEndianChange(INT) 字节序转换(静态方法)按32位转换参数的字节序一些云平台的环境变量中IP信息可能是Little-Endian形式的数值;比如百度node.js环境中的 process.env.BAE_ENV_COOKIE_IP , 这时候就有用了;> qqwry.ipEndianChange(0x010000FF) 4278190081 //0xFF000001文档说明./data/qqwry.dat  默认IP,可用最新I

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值