<?php

/**
* 纯真IP根据IP地址获得地址
*/ class ipLocation { public $fp; public $firstip; //第一条ip索引的偏移地址 public $lastip; //最后一条ip索引的偏移地址 public $totalip; //总ip数 // //* //构造函数,初始化一些变量 //$datfile 的值为纯真IP数据库的名子,可自行修改. //* function __construct($datfile = "CoralWry.dat") { $filepath = APP_CLASS . 'Public/CoralWry.dat'; $this->fp = fopen($filepath, 'rb'); //二制方式打开 $this->firstip = $this->get4b(); //第一条ip索引的绝对偏移地址 $this->lastip = $this->get4b(); //最后一条ip索引的绝对偏移地址 $this->totalip = ($this->lastip - $this->firstip) / 7; //ip总数 索引区是定长的7个字节,在此要除以7, register_shutdown_function(array($this, "closefp")); //为了兼容php5以下版本,本类没有用析构函数,自动关闭ip库. } //* //关闭ip库 //* function closefp() { fclose($this->fp); } //* //读取4个字节并将解压成long的长模式 //* function get4b() { $str = unpack("V", fread($this->fp, 4)); return $str[1]; } //* //读取重定向了的偏移地址 //* function getoffset() { $str = unpack("V", fread($this->fp, 3) . chr(0)); return $str[1]; } //* //读取ip的详细地址信息 //* function getstr() { $split = fread($this->fp, 1); while (ord($split) != 0) { $str .=$split; $split = fread($this->fp, 1); } return $str; } //* //将ip通过ip2long转成ipv4的互联网地址,再将他压缩成big-endian字节序 //用来和索引区内的ip地址做比较 //* function iptoint($ip) { return pack("N", intval(ip2long($ip))); } //* //获取客户端ip地址 //注意:如果你想要把ip记录到服务器上,请在写库时先检查一下ip的数据是否安全. //* function getIP() { if (getenv('HTTP_CLIENT_IP')) { $ip = getenv('HTTP_CLIENT_IP'); } elseif (getenv('HTTP_X_FORWARDED_FOR')) { //获取客户端用代理服务器访问时的真实ip 地址 $ip = getenv('HTTP_X_FORWARDED_FOR'); } elseif (getenv('HTTP_X_FORWARDED')) { $ip = getenv('HTTP_X_FORWARDED'); } elseif (getenv('HTTP_FORWARDED_FOR')) { $ip = getenv('HTTP_FORWARDED_FOR'); } elseif (getenv('HTTP_FORWARDED')) { $ip = getenv('HTTP_FORWARDED'); } else { $ip = $_SERVER['REMOTE_ADDR']; } return $ip; } //* //获取地址信息 //* function readaddress() { $now_offset = ftell($this->fp); //得到当前的指针位址 $flag = $this->getflag(); switch (ord($flag)) { case 0: $address = ""; break; case 1: case 2: fseek($this->fp, $this->getoffset()); $address = $this->getstr(); break; default: fseek($this->fp, $now_offset); $address = $this->getstr(); break; } return $address; } //* //获取标志1或2 //用来确定地址是否重定向了. //* function getflag() { return fread($this->fp, 1); } //* //用二分查找法在索引区内搜索ip //* function searchip($ip) { $ip = gethostbyname($ip); //将域名转成ip $ip_offset["ip"] = $ip; $ip = $this->iptoint($ip); //将ip转换成长整型 $firstip = 0; //搜索的上边界 $lastip = $this->totalip; //搜索的下边界 $ipoffset = $this->lastip; //初始化为最后一条ip地址的偏移地址 while ($firstip <= $lastip) { $i = floor(($firstip + $lastip) / 2); //计算近似中间记录 floor函数记算给定浮点数小的最大整数,说白了就是四舍五也舍 fseek($this->fp, $this->firstip + $i * 7); //定位指针到中间记录 $startip = strrev(fread($this->fp, 4)); //读取当前索引区内的开始ip地址,并将其little-endian的字节序转换成big-endian的字节序 if ($ip < $startip) { $lastip = $i - 1; } else { fseek($this->fp, $this->getoffset()); $endip = strrev(fread($this->fp, 4)); if ($ip > $endip) { $firstip = $i + 1; } else { $ip_offset["offset"] = $this->firstip + $i * 7; break; } } } return $ip_offset; } //* //获取ip地址详细信息 //* function getaddress($ip) { $ip_offset = $this->searchip($ip); //获取ip 在索引区内的绝对编移地址 $ipoffset = $ip_offset["offset"]; $address["ip"] = $ip_offset["ip"]; fseek($this->fp, $ipoffset); //定位到索引区 $address["startip"] = long2ip($this->get4b()); //索引区内的开始ip 地址 $address_offset = $this->getoffset(); //获取索引区内ip在ip记录区内的偏移地址 fseek($this->fp, $address_offset); //定位到记录区内 $address["endip"] = long2ip($this->get4b()); //记录区内的结束ip 地址 $flag = $this->getflag(); //读取标志字节 switch (ord($flag)) { case 1: //地区1地区2都重定向 $address_offset = $this->getoffset(); //读取重定向地址 fseek($this->fp, $address_offset); //定位指针到重定向的地址 $flag = $this->getflag(); //读取标志字节 switch (ord($flag)) { case 2: //地区1又一次重定向, fseek($this->fp, $this->getoffset()); $address["area1"] = $this->getstr(); fseek($this->fp, $address_offset + 4); //跳4个字节 $address["area2"] = $this->readaddress(); //地区2有可能重定向,有可能没有 break; default: //地区1,地区2都没有重定向 fseek($this->fp, $address_offset); //定位指针到重定向的地址 $address["area1"] = $this->getstr(); $address["area2"] = $this->readaddress(); break; } break; case 2: //地区1重定向 地区2没有重定向 $address1_offset = $this->getoffset(); //读取重定向地址 fseek($this->fp, $address1_offset); $address["area1"] = $this->getstr(); fseek($this->fp, $address_offset + 8); $address["area2"] = $this->readaddress(); break; default: //地区1地区2都没有重定向 fseek($this->fp, $address_offset + 4); $address["area1"] = $this->getstr(); $address["area2"] = $this->readaddress(); break; } //*过滤一些无用数据 if (strpos($address["area1"], "CZ88.NET") != false) { $address["area1"] = "未知"; } if (strpos($address["area2"], "CZ88.NET") != false) { $address["area2"] = " "; } $address['area1'] = Fun::gbkToutf8($address['area1']); $address['area2'] = Fun::gbkToutf8($address['area2']); $address['loc'] = $address['area1'] . ' ' . $address['area2']; return $address; } } ?>

纯真IP根据IP地址获得地址的更多相关文章

  1. 几种获取IP 根据IP获取地址的方法 JS,第三方 新浪 网易 腾讯

    第一种是利用纯真ip数据库,这个可以在网上找到很多,缺点是更新有点慢. 第二种是利用门户网站的接口 目前已知的有腾讯.新浪.网易.搜狐和Google提供IP地址查询API,但是找得到的只有腾讯.新浪和 ...

  2. QT通过IP地址定位地址(用get方法取数据)

    通过IP地址定位地址,是要通过查询数据库,如果自己做一个这样的数据库工作量就比较大,所以在网上找了一个查询IP地址的网址,通过调用这个网址查询来实现,但是这个有一定的弊端,如果没有网络或者这个网址不可 ...

  3. php禁止某ip或ip地址段访问的方法(转载)

    <?php include("banIP.php");?> 禁用单个ip如下:<?php //禁用ip地址 $ip=$_SERVER["REMOTE_A ...

  4. IP,IP地址,mac地址

    IP地址与IP是两个不同的概念.单独讲IP,是指IP协议 IP地址分为三类:单播地址(目的为单个主机):多播地址(目的端为同一组的所有主机):广播地址(目的端为网络上所有给定的主机) ip地址由网络和 ...

  5. JS获取客户端公网IP和IP地址

    网上解决方案 1.通过搜狐接口 获取方式如下: //网页端引入脚本 <script type="text/javascript" src="http://pv.so ...

  6. 通过IP获取对应所在地的地址

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wangshuxuncom/article/details/35988143         曾几何时 ...

  7. IP 和 IP地址的区别和联系

    IP(internet protocol) 网际协议 和IP地址有人会把“IP”和“IP 地址”搞混,“IP”其实是一种协议的名称.IP 协议的作用是把各种数据包传送给对方.而要保证确实传送到对方那里 ...

  8. 嵌入式Linux可用的防火墙——iptables:实现ip白名单、mac地址白名单

    iptables是linux系统下的一个功能强大的模块,不仅可以用作防火墙,还可以实现NAT等众多路由功能.iptables的容器有很清晰的层次关系: 1. iptables是表的容器,iptable ...

  9. Windows Azure Virtual Network (7) 设置Azure Virtual Machine固定公网IP (Virtual IP Address, VIP) (2)

    <Windows Azure Platform 系列文章目录> 本文介绍的是,当用户在创建Azure Virtual Machine的时候,忘记绑定公网IP,需要重新绑定公网IP的具体操作 ...

随机推荐

  1. HTMO DOM部分---小练习;列表之间移动、日期选择、好友选中、滑动效果、滚动条效果、飞入飞出效果。

    一:列表之间数据移动 第一个列表里面有内容,第二个里面没有 实现功能: 点击左侧列表选中一项内容,点击按钮,复制到右侧 点击复制所有按钮,将左侧列表所有数据,复制到右侧 扩展功能:右侧列表实现去重复 ...

  2. 不容易系列之(3)—— LELE的RPG难题

    有排成一行的n个方格,用红(Red).粉(Pink).绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法. 思路:运用递归算法. a[1 ...

  3. JavaWeb学习记录(十五)——浏览器Cookie禁用后的处理

    IE禁用Cookie方式:

  4. Ansible安装配置Nginx

    一.思路 现在一台机器上编译安装好nginx.打包,然后在用ansible去下发 cd /etc/ansible 进入ansible配置文件目录 mkdir roles/{common,install ...

  5. php连接MongoDB

    一.安装php的mongo扩展 # wget https://github.com/mongodb/mongo-php-driver-legacy/archive/master.zip -O /usr ...

  6. 课堂所讲整理:HTML--7JavaScript的DOM操作

    1.DOM的基本概念 DOM是文档对象模型,这种模型为树模型:文档是指标签文档:对象是指文档中每个元素:模型是指抽象化的东西. 2.Window对象操作 一.属性和方法: 属性(值或者子对象): op ...

  7. Android——不同activity之间数据传递

    /* * 不同activity之间数据的传递 */ public class MainActivity extends Activity { private EditText et_name; @Ov ...

  8. What are the main disadvantages of Java Server Faces 2.0?

    http://stackoverflow.com/questions/3623911/what-are-the-main-disadvantages-of-java-server-faces-2-0/ ...

  9. 使得<li>在一行显示,去除浮动的方法

    ①<li>使用浮动的方法,但是要用div包裹起来,该父元素需要设置宽度与高度: <!DOCTYPE html> <html> <head> <me ...

  10. linux概念之内存分析

    linux内存总结 分析样本[root@-comecs ~]# free total used free shared buffers cached Mem: -/+ buffers/cache: S ...