php读取纯真ip数据库使用示例

 这篇文章主要介绍了php读取纯真ip数据库显示详细信息的使用示例,大家参考使用吧

 代码如下:
<?php
/*--------------------------------------------------
 ip2address [qqwry.dat]
--------------------------------------------------*/
 
class ip {
 var $fh; //IP数据库文件句柄
 var $first; //第一条索引
 var $last; //最后一条索引
 var $total; //索引总数
 
 //构造函数
 function __construct() {
  $this->fh = fopen('qqwry.dat', 'rb'); //qqwry.dat文件
  $this->first = $this->getLong4();
  $this->last = $this->getLong4();
  $this->total = ($this->last - $this->first) / 7; //每条索引7字节
 }
 
 //检查IP合法性
 function checkIp($ip) {
  $arr = explode('.',$ip);
  if(count($arr) !=4 ) {
   return false;
  } else {
   for ($i=0; $i < 4; $i++) {
    if ($arr[$i] <'0' || $arr[$i] > '255') {
     return false;
    }
   }
  }
  return true;
 }
 
 function getLong4() {
  //读取little-endian编码的4个字节转化为长整型数
  $result = unpack('Vlong', fread($this->fh, 4));
  return $result['long'];
 }
 
 function getLong3() {
  //读取little-endian编码的3个字节转化为长整型数
  $result = unpack('Vlong', fread($this->fh, 3).chr(0));
  return $result['long'];
 }
 
 //查询信息
 function getInfo($data = "") {
  $char = fread($this->fh, 1);
  while (ord($char) != 0) { //国家地区信息以0结束
   $data .= $char;
   $char = fread($this->fh, 1);
  }
  return $data;
 }
 
 //查询地区信息
 function getArea() {
  $byte = fread($this->fh, 1); //标志字节
  switch (ord($byte)) {
   case 0: $area = ''; break; //没有地区信息
   case 1: //地区被重定向
    fseek($this->fh, $this->getLong3());
    $area = $this->getInfo(); break;
   case 2: //地区被重定向
   fseek($this->fh, $this->getLong3());
   $area = $this->getInfo(); break;
   default: $area = $this->getInfo($byte);  break; //地区没有被重定向
  }
  return $area;
 }
 
 function ip2addr($ip) {
  if(!$this -> checkIp($ip)){
   return false;
  }
 
  $ip = pack('N', intval(ip2long($ip)));
 
  //二分查找
  $l = 0;
  $r = $this->total;
 
  while($l <= $r) {
   $m = floor(($l + $r) / 2); //计算中间索引
   fseek($this->fh, $this->first + $m * 7);
   $beginip = strrev(fread($this->fh, 4)); //中间索引的开始IP地址
   fseek($this->fh, $this->getLong3());
   $endip = strrev(fread($this->fh, 4)); //中间索引的结束IP地址
 
   if ($ip < $beginip) { //用户的IP小于中间索引的开始IP地址时
    $r = $m - 1;
   } else {
    if ($ip > $endip) { //用户的IP大于中间索引的结束IP地址时
     $l = $m + 1;
    } else { //用户IP在中间索引的IP范围内时
     $findip = $this->first + $m * 7;
     break;
    }
   }
  }
 
  //查询国家地区信息
  fseek($this->fh, $findip);
  $location['beginip'] = long2ip($this->getLong4()); //用户IP所在范围的开始地址
  $offset = $this->getlong3();
  fseek($this->fh, $offset);
  $location['endip'] = long2ip($this->getLong4()); //用户IP所在范围的结束地址
  $byte = fread($this->fh, 1); //标志字节
  switch (ord($byte)) {
   case 1:  //国家和区域信息都被重定向
    $countryOffset = $this->getLong3(); //重定向地址
    fseek($this->fh, $countryOffset);
    $byte = fread($this->fh, 1); //标志字节
    switch (ord($byte)) {
     case 2: //国家信息被二次重定向
      fseek($this->fh, $this->getLong3());
      $location['country'] = $this->getInfo();
      fseek($this->fh, $countryOffset + 4);
      $location['area'] = $this->getArea();
      break;
     default: //国家信息没有被二次重定向
      $location['country'] = $this->getInfo($byte);
      $location['area'] = $this->getArea();
      break;
    }
    break;
 
   case 2: //国家信息被重定向
    fseek($this->fh, $this->getLong3());
    $location['country'] = $this->getInfo();
    fseek($this->fh, $offset + 8);
    $location['area'] = $this->getArea();
    break;
 
   default: //国家信息没有被重定向
    $location['country'] = $this->getInfo($byte);
    $location['area'] = $this->getArea();
    break;
  }
 
  //gb2312 to utf-8(去除无信息时显示的CZ88.NET)
  foreach ($location as $k => $v) {
   $location[$k] = str_replace('CZ88.NET','',iconv('gb2312', 'utf-8', $v));
  }
 
  return $location;
 }
 
 //析构函数
 function __destruct() {
  fclose($this->fh);
 }
}
 
$ip = new ip();
$addr = $ip -> ip2addr('IP地址');
print_r($addr);
?>

时间: 2024-11-02 00:16:40

php读取纯真ip数据库使用示例的相关文章

php读取纯真ip数据库使用示例_php实例

复制代码 代码如下: <?php/*-------------------------------------------------- ip2address [qqwry.dat]--------------------------------------------------*/ class ip { var $fh; //IP数据库文件句柄 var $first; //第一条索引 var $last; //最后一条索引 var $total; //索引总数  //构造函数 functio

读取纯真IP数据库的公用组件接口QQWry.NET_实用技巧

这是一个读取纯真IP数据库的公用组件接口,我是通过luma的<纯真IP数据库格式详解>了解了纯真IP数据库数据格式,并且基于网络上的一个IPLocation.dll源码的基础改编而来.我为什么要改编这个组件呢?因为我看到这个组件在使用过程中,每次都要打开文件流,并且整个接口使用静态的属性.并不适合Web环境下,多线程并发查询的需求,并且在性能上也不是最优.有了luma的格式详解,和现有的IPLocation.dll的源码,使我的工作变得异常的简单.出现的一个小错误,也是经过一次调试后就解决了.

asp.net/C#读取纯真IP数据库

C#读取纯真IP数据库 免费下载地址:http://download.csdn.net/detail/virone/4568159 using System; using System.Collections.Generic; using System.Text; using System.IO; namespace 纯真IP数据库研究 {     ///<summary>     /// 提供从纯真IP数据库搜索IP信息的方法:     /// 感谢LumaQQ提供纯真IP数据库格式文档:

Discuz 5.0 中读取纯真IP数据库函数分析

函数|数据|数据库 Discuz  5.0 不在使用自己的IP数据,而是使用纯真IP的数据格式, 存取纯真IP数据库稍微有点麻烦,它的存储格式比较特殊也很有趣,具体的格式分析参考下面两个链接,其他语言实现参考文章末的链接. <纯真IP数据库格式详解>链接一:http://blog.csdn.net/heiyeshuwu/archive/2006/05/12/725675.aspx链接二:http://lumaqq.linuxsir.org/article/qqwry_format_detail

UTF-8使用纯真IP数据库乱码问题

最近手头在写一个根据IP地址返回省份地区的代码,发现在使用纯真ip数据库的时候出现乱码,最后发现纯真数据库是居于GBK编码的,而我的整个工程编码都是采用的UTF-8编码,两个走到一起肯定会出现乱码,所以只能改写纯真读取ip的类 <% '得到访问者IP public Function getip() Dim strIPAddr If Request.ServerVariables("HTTP_X_FORWARDED_FOR") = "" OR InStr(Req

PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)_php实例

如下所示: <?php $data = '254.254.254.254'; echo ip2long($data); function getIP() { if(getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) $ip = getenv("HTTP_CLIENT_IP"); elseif(getenv

Discuz 5.0 中读取纯真IP数据库函数分析_php技巧

Discuz  5.0 不在使用自己的IP数据,而是使用纯真IP的数据格式, 存取纯真IP数据库稍微有点麻烦,它的存储格式比较特殊也很有趣,具体的格式分析参考下面两个链接,其他语言实现参考文章末的链接. <纯真IP数据库格式详解> 链接一:http://blog.csdn.net/heiyeshuwu/archive/2006/05/12/725675.aspx 链接二:http://lumaqq.linuxsir.org/article/qqwry_format_detail.html 纯真

纯真IP数据库格式图文详解_应用技巧

摘要 网络上的IP数据库以纯真版的最为流行,LumaQQ也采用了纯真版IP数据库做为IP查询功能的基础.不过关于其格式的文档却非常之少,后来终于在网上找到了一份文档,得以了解其内幕,不过那份文档寥寥数语,也是颇为耐心才读明白.在这里我重写一份,以此做为LumaQQ开发者文档的一部分,我想还是必要的.本文详细介绍了纯真IP数据库的格式,并且给出了一些Demo以供参考. Luma, 清华大学修改日期: 2005/01/14 Note: 在此感谢纯真IP数据库作者金狐和那唯一一份文档的作者. 修改历史

python访问纯真IP数据库的代码_python

核心代码: #!/usr/bin/env python # -*- coding: utf-8 -*- from bisect import bisect _LIST1, _LIST2 = [], [] _INIT = False ip2int = lambda ip_str: reduce(lambda a, b: (a << 8) + b, [int(i) for i in ip_str.split('.')]) def _init(): global _LIST, _INIT if no