<?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. 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) G 优先队列

    G. Car Repair Shop time limit per test 2 seconds memory limit per test 512 megabytes input standard ...

  2. 使用isInEditMode解决可视化编辑器无法识别自定义控件的问题

    如果在自定义控件的构造函数或者其他绘制相关地方使用系统依赖的代码, 会导致可视化编辑器无法报错并提示:Use View.isInEditMode() in your custom views to s ...

  3. tulterbot遥感操作使用Interactive Markers--12

    原创博客:转载请表明出处:http://www.cnblogs.com/zxouxuewei/ 1.安装ros indigo功能包: sudo apt-get install ros-indigo-t ...

  4. Codeforces Round #111 (Div. 2)

    Codeforces Round #111 (Div. 2) C. Find Pair 题意 给\(N(N \le 10^5)\)个数,在所有\(N^2\)对数中求第\(K(K \le N^2)\)对 ...

  5. Java设计模式之简单工厂设计模式

    简单工厂将业务逻辑部分和界面逻辑部分分离开来,降低了界面逻辑和业务逻辑的耦合度,符合面向对象迪米特法则.下面以一个加法减法运算器为例,各位读者可以自行按照这种设计方式设计出一个小小的运算器. 1.业务 ...

  6. QAction类详解:

    先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...

  7. ob_start()失效与phpunit的非正常结束

    在ob_clean();或ob_get_clean()之前有return或致命错误,从而结束了程序,会导致ob_start失效, 这和phpunit的非正常结束

  8. PostgreSQL and bloat

    The bucardo project has released its nagios plugins for PostgreSQL and we can extract from them this ...

  9. 斐波那契数列PHP非递归数组实现

    概念: 斐波那契数列即表达式为 a(n) = a(n-1)+a(n-2) 其中 a1 =0 a2 = 1  的数列 代码实现功能: 该类实现初始化给出n,通过调用getValue函数得出a(n)的值 ...

  10. 在OCR文字识别软件选项卡中怎么设置图像和文字

    PDF是广泛使用的文档格式.在ABBYY Finereader中,PDF文档的显示不会因电脑不同而有差异,可加密保护,非常适合在电子存档中进行保存.下面给 大家讲解如何在PDF选项设置图像和文字. 图 ...