<?php
if( !function_exists('ftok') )
{
function ftok($filename = "", $proj = "")
{
if( empty($filename) ││ !file_exists($filename) )
{
return -1;
}
else
{
$filename = $filename . (string) $proj;
for($key = array(); sizeof($key) < strlen($filename); $key[] = ord(substr($filename, sizeof($key), 1)));
return array_sum($key);
}
}
}
class IpLocation {
var $shm_id;
var $firstip;
var $lastip;
var $totalip;
var $pos;
function getlong() {
$result = unpack('Vlong', shmop_read($this->shm_id, $this->pos, 4));
$this->pos += 4;
return $result['long'];
}
function getlong3() {
$result = unpack('Vlong', shmop_read($this->shm_id, $this->pos, 3).chr(0));
$this->pos += 3;
return $result['long'];
}
function packip($ip) {
return pack('N', intval(ip2long($ip)));
}
function getstring($data = "") {
$char = shmop_read($this->shm_id, $this->pos++, 1);
while (ord($char) > 0) {
$data .= $char;
$char = shmop_read($this->shm_id, $this->pos++, 1);
}
return $data;
}
function getarea() {
$byte = shmop_read($this->shm_id, $this->pos++, 1);
switch (ord($byte)) {
case 0:
$area = "";
break;
case 1:
case 2:
$this->pos = $this->getlong3($this->pos);
$area = $this->getstring();
break;
default:
$area = $this->getstring($byte);
break;
}
return $area;
}
function getlocation($ip) {
if (!$this->shm_id) return null;
$location['ip'] = gethostbyname($ip);
$ip = $this->packip($location['ip']);
$l = 0;
$u = $this->totalip;
$findip = $this->lastip;
while ($l <= $u) {
$i = floor(($l + $u) / 2);
$this->pos = $this->firstip + $i * 7;
$beginip = strrev(shmop_read($this->shm_id, $this->pos, 4));
if ($ip < $beginip) {
$u = $i - 1;
}
else {
$this->pos += 4;
$this->pos = $this->getlong3();
$endip = strrev(shmop_read($this->shm_id, $this->pos, 4));
if ($ip > $endip) {
$l = $i + 1;
}
else {
$findip = $this->firstip + $i * 7;
break;
}
}
}
$this->pos = $findip;
$location['beginip'] = long2ip($this->getlong());
$this->pos = $offset = $this->getlong3();
$location['endip'] = long2ip($this->getlong());
$byte = shmop_read($this->shm_id, $this->pos++, 1);
switch (ord($byte)) {
case 1:
$this->pos = $countryOffset = $this->getlong3();
$byte = shmop_read($this->shm_id, $this->pos++, 1);
switch (ord($byte)) {
case 2:
$this->pos = $this->getlong3();
$location['country'] = $this->getstring();
$this->pos = $countryOffset + 4;
$location['area'] = $this->getarea();
break;
default:
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
break;
case 2:
$this->pos = $this->getlong3();
$location['country'] = $this->getstring();
$this->pos = $offset + 8;
$location['area'] = $this->getarea();
break;
default:
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
if ($location['country'] == " CZ88.NET") {
$location['country'] = "未知";
}
if ($location['area'] == " CZ88.NET") {
$location['area'] = "";
}
return $location;
}
function IpLocation($filename) {
$shm_key = ftok($filename, 'R');
if (!($this->shm_id = @shmop_open($shm_key, "a", 0, 0))) {
$content = file_get_contents($filename);
$this->shm_id = shmop_open($shm_key, "c", 0644, strlen($content));
shmop_write($this->shm_id, $content, 0);
}
$this->pos = 0;
$this->firstip = $this->getlong();
$this->lastip = $this->getlong();
$this->totalip = ($this->lastip - $this->firstip) / 7;
register_shutdown_function(array(&$this, '_IpLocation'));
}
function _IpLocation() {
shmop_close($this->shm_id);
}
function &getInstance($filename = "QQWry.Dat") {
static $instance = null;
if (is_null($instance)) {
$instance = new IpLocation($filename);
}
return $instance;
}
}
?>