珊瑚虫IP库PHP操作类
| < ?php |
| class IpLocation{ |
| private $fp; |
| private $wrydat; |
| private $wrydat_version; |
| private $ipnumber; |
| private $firstip; |
| private $lastip; |
| private $ip_range_begin; |
| private $ip_range_end; |
| private $country; |
| private $area; |
| const REDIRECT_MODE_0 = 0; |
| const REDIRECT_MODE_1 = 1; |
| const REDIRECT_MODE_2 = 2; |
| function __construct(){ |
| $args = func_get_args(); |
| $this->wrydat = func_num_args()>0?$args[0]:'CoralWry.dat'; |
| $this->initialize(); |
| } |
| function __destruct(){ |
| fclose($this->fp); |
| } |
| private function initialize(){ |
| if(file_exists($this->wrydat)) |
| $this->fp = fopen($this->wrydat,'rb'); |
| $this->getipnumber(); |
| $this->getwryversion(); |
| } |
| public function get($str){ |
| return $this->$str; |
| } |
| public function set($str,$val){ |
| $this->$str = $val; |
| } |
| private function getbyte($length,$offset=null){ |
| if(!is_null($offset)){ |
| fseek($this->fp,$offset,SEEK_SET); |
| } |
| $b = fread($this->fp,$length); |
| return $b; |
| } |
| /** |
| * 把IP地址打包成二进制数据,以big endian(高位在前)格式打包 |
| * 数据存储格式为 little endian(低位在前) 如: |
| * 00 28 C6 DA 218.198.40.0 little endian |
| * 3F 28 C6 DA 218.198.40.0 little endian |
| * 这样的数据无法作二分搜索查找的比较,所以必须先把获得的IP数据使用strrev转换为big endian |
| * @param $ip |
| * @return big endian格式的二进制数据 |
| */ |
| private function packip($ip){ |
| return pack( "N", intval( ip2long( $ip))); |
| } |
| private function getlong($length=4, $offset=null){ |
| $chr=null; |
| for($c=0;$length%4!=0&&$c< (4-$length%4);$c++){ |
| $chr .= chr(0); |
| } |
| $var = unpack( "Vlong", $this->getbyte($length, $offset).$chr); |
| return $var['long']; |
| } |
| private function getwryversion(){ |
| $length = preg_match("/coral/i",$this->wrydat)?26:30; |
| $this->wrydat_version = $this->getbyte($length, $this->firstip-$length); |
| } |
| private function getipnumber(){ |
| $this->firstip = $this->getlong(); |
| $this->lastip = $this->getlong(); |
| $this->ipnumber = ($this->lastip-$this->firstip)/7+1; |
| } |
| private function getstring($data="",$offset=null){ |
| $char = $this->getbyte(1,$offset); |
| while(ord($char) > 0){ |
| $data .= $char; |
| $char = $this->getbyte(1); |
| } |
| return $data; |
| } |
| private function iplocaltion($ip){ |
| $ip = $this->packip($ip); |
| $low = 0; |
| $high = $this->ipnumber-1; |
| $ipposition = $this->lastip; |
| while($low < = $high){ |
| $t = floor(($low+$high)/2); |
| if($ip < strrev($this->getbyte(4,$this->firstip+$t*7))){ |
| $high = $t - 1; |
| } else { |
| if($ip > strrev($this->getbyte(4,$this->getlong(3)))){ |
| $low = $t + 1; |
| }else{ |
| $ipposition = $this->firstip+$t*7; |
| break; |
| } |
| } |
| } |
| return $ipposition; |
| } |
| private function getarea(){ |
| $b = $this->getbyte(1); |
| switch(ord($b)){ |
| case self::REDIRECT_MODE_0 : |
| return "未知"; |
| break; |
| case self::REDIRECT_MODE_1: |
| case self::REDIRECT_MODE_2: |
| return $this->getstring("",$this->getlong(3)); |
| break; |
| default: |
| return $this->getstring($b); |
| break; |
| } |
| } |
| public function getiplocation($ip){ |
| $ippos = $this->iplocaltion($ip); |
| $this->ip_range_begin = long2ip($this->getlong(4,$ippos)); |
| $this->ip_range_end = long2ip($this->getlong(4,$this->getlong(3))); |
| $b = $this->getbyte(1); |
| switch (ord($b)){ |
| case self::REDIRECT_MODE_1: |
| $b = $this->getbyte(1,$this->getlong(3)); |
| if(ord($b) == REDIRECT_MODE_2){ |
| $countryoffset = $this->getlong(3); |
| $this->area = $this->getarea(); |
| $this->country = $this->getstring("",$countryoffset); |
| }else{ |
| $this->country = $this->getstring($b); |
| $this->area = $this->getarea(); |
| } |
| break; |
| case self::REDIRECT_MODE_2: |
| $countryoffset = $this->getlong(3); |
| $this->area = $this->getarea(); |
| $this->country = $this->getstring("",$countryoffset); |
| break; |
| default: |
| $this->country = $this->getstring($b); |
| $this->area = $this->getarea(); |
| break; |
| } |
| } |
| } |
| /* */ |
| echo microtime(); |
| echo "\n"; |
| $iploca = new IpLocation; |
| //$iploca = new IpLocation('QQWry.dat'); |
| echo $iploca->get('wrydat_version'); |
| echo "\n"; |
| echo $iploca->get('ipnumber'); |
| echo "\n"; |
| $iploca->getiplocation('211.44.32.34'); |
| /**/ |
| echo $iploca->get('ip_range_begin'); |
| echo "\n"; |
| echo $iploca->get('ip_range_end'); |
| echo "\n"; |
| echo $iploca->get('country'); |
| echo "\n"; |
| echo $iploca->get('area'); |
| echo "\n"; |
| echo $iploca->get('lastip'); |
| echo "\n"; |
| echo microtime(); |
| echo "\n"; |
| unset($iploca); |
| ?> |

你好,很感谢你的内容,感觉很好.学习了下.