纯真IP根据IP地址获得地址
<?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地址获得地址的更多相关文章
- 几种获取IP 根据IP获取地址的方法 JS,第三方 新浪 网易 腾讯
第一种是利用纯真ip数据库,这个可以在网上找到很多,缺点是更新有点慢. 第二种是利用门户网站的接口 目前已知的有腾讯.新浪.网易.搜狐和Google提供IP地址查询API,但是找得到的只有腾讯.新浪和 ...
- QT通过IP地址定位地址(用get方法取数据)
通过IP地址定位地址,是要通过查询数据库,如果自己做一个这样的数据库工作量就比较大,所以在网上找了一个查询IP地址的网址,通过调用这个网址查询来实现,但是这个有一定的弊端,如果没有网络或者这个网址不可 ...
- php禁止某ip或ip地址段访问的方法(转载)
<?php include("banIP.php");?> 禁用单个ip如下:<?php //禁用ip地址 $ip=$_SERVER["REMOTE_A ...
- IP,IP地址,mac地址
IP地址与IP是两个不同的概念.单独讲IP,是指IP协议 IP地址分为三类:单播地址(目的为单个主机):多播地址(目的端为同一组的所有主机):广播地址(目的端为网络上所有给定的主机) ip地址由网络和 ...
- JS获取客户端公网IP和IP地址
网上解决方案 1.通过搜狐接口 获取方式如下: //网页端引入脚本 <script type="text/javascript" src="http://pv.so ...
- 通过IP获取对应所在地的地址
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wangshuxuncom/article/details/35988143 曾几何时 ...
- IP 和 IP地址的区别和联系
IP(internet protocol) 网际协议 和IP地址有人会把“IP”和“IP 地址”搞混,“IP”其实是一种协议的名称.IP 协议的作用是把各种数据包传送给对方.而要保证确实传送到对方那里 ...
- 嵌入式Linux可用的防火墙——iptables:实现ip白名单、mac地址白名单
iptables是linux系统下的一个功能强大的模块,不仅可以用作防火墙,还可以实现NAT等众多路由功能.iptables的容器有很清晰的层次关系: 1. iptables是表的容器,iptable ...
- Windows Azure Virtual Network (7) 设置Azure Virtual Machine固定公网IP (Virtual IP Address, VIP) (2)
<Windows Azure Platform 系列文章目录> 本文介绍的是,当用户在创建Azure Virtual Machine的时候,忘记绑定公网IP,需要重新绑定公网IP的具体操作 ...
随机推荐
- ZOJ 1095 Humble Numbers
原题链接 题目大意:定义了一种数字Humble Number,他们的质因数只包含2.3.5.7中的一个或者几个,求第n个这样的数,1<=n<=5842. 解法:一看到这道题又在想DFS了, ...
- POJ 1043 What's In A Name?(唯一的最大匹配方法)
What's In A Name? Time Limit: 1000MS Memor ...
- 黑马程序员——JAVA基础之简述集合collection
------- android培训.java培训.期待与您交流! ---------- 集合: 为什么出现集合类? • 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对 ...
- 黑马程序员——JAVA基础之包,权限
------- android培训.java培训.期待与您交流! ---------- 包(package) 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称的是:包 ...
- Java 学习
effective+java第三版 2016-09-23 15:25 effective+java第三版 相关问答 EffectiveJava第28条中关于泛型的一个疑问? @又名耶稣谢邀 一.先说说 ...
- Unity Meshes
1. Unity 没有自带建模工具 2. 导入 Mesh 时,Unity 会自动寻找所引用的纹理,查找文件夹名为 Textures 的.先在本目录下找 -> 上溯在parent查找 ==> ...
- A Flock Of Tasty Sources On How To Start Learning High Scalability
This is a guest repost by Leandro Moreira. When we usually are interested about scalability we look ...
- c# 图片XML序列化与反序列化
var xmlDoc = new XmlDocument(); xmlDoc.Load(@"C:\Users\*\Desktop\*.xml"); ].ChildNodes[]; ...
- 怎么给OCR文字识别软件设置正确的扫描分辨率
ABBYY FineReader 12是一款专业的OCR文字识别软件,可快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜索的文本,不仅支持对页扫描,还支持多页扫描,扫描分辨率的选 ...
- 二十四种设计模式:提供者模式(Provider Pattern)
提供者模式(Provider Pattern) 介绍为一个API进行定义和实现的分离.示例有一个Message实体类,对它的操作有Insert()和Get()方法,持久化数据在SqlServer数据库 ...