<?php /** * parse ip use http://www.cz88.net database */ class QQIp { protected $fp; function __construct($file) { if (! is_file($file)) { user_error('file is not found, file=' . $file, E_USER_ERROR); } $this->fp = fopen($file, 'rb'); if (! is_resource($this->fp)) { user_error('can not open file, file=' . $file, E_USER_ERROR); } } /** * * @param string $ip */ function parse($ip) { $fp = $this->fp; $ip = explode('.', $ip); $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3]; // get start position and end position from db $DataBegin = fread($fp, 4); $DataEnd = fread($fp, 4); $ipbegin = implode('', unpack('L', $DataBegin)); if ($ipbegin < 0) $ipbegin += pow(2, 32); $ipend = implode('', unpack('L', $DataEnd)); if ($ipend < 0) $ipend += pow(2, 32); $ipAllNum = ($ipend - $ipbegin) / 7 + 1; $BeginNum = 0; $EndNum = $ipAllNum; $ip1num = null; $ip2num = null; // find ip from index use dichotomy while ($ip1num > $ipNum || $ip2num < $ipNum) { $Middle = intval(($EndNum + $BeginNum) / 2); // set the pointer to index position and read 4 byte fseek($fp, $ipbegin + 7 * $Middle); $ipData1 = fread($fp, 4); if (strlen($ipData1) < 4) { fclose($fp); return '- System Error'; } // convert value to long.Add 2^32 if value is negative $ip1num = implode('', unpack('L', $ipData1)); if ($ip1num < 0) $ip1num += pow(2, 32); // change end position if value greate than ip address if ($ip1num > $ipNum) { $EndNum = $Middle; continue; } // get next index $DataSeek = fread($fp, 3); if (strlen($DataSeek) < 3) { fclose($fp); return '- System Error'; } $DataSeek = implode('', unpack('L', $DataSeek . chr(0))); fseek($fp, $DataSeek); $ipData2 = fread($fp, 4); if (strlen($ipData2) < 4) { fclose($fp); return '- System Error'; } $ip2num = implode('', unpack('L', $ipData2)); if ($ip2num < 0) $ip2num += pow(2, 32); // not found if ($ip2num < $ipNum) { if ($Middle == $BeginNum) { fclose($fp); return '- Unknown'; } $BeginNum = $Middle; } } $ipFlag = fread($fp, 1); if ($ipFlag == chr(1)) { $ipSeek = fread($fp, 3); if (strlen($ipSeek) < 3) { fclose($fp); return '- System Error'; } $ipSeek = implode('', unpack('L', $ipSeek . chr(0))); fseek($fp, $ipSeek); $ipFlag = fread($fp, 1); } if ($ipFlag == chr(2)) { $AddrSeek = fread($fp, 3); if (strlen($AddrSeek) < 3) { fclose($fp); return '- System Error'; } $ipFlag = fread($fp, 1); if ($ipFlag == chr(2)) { $AddrSeek2 = fread($fp, 3); if (strlen($AddrSeek2) < 3) { fclose($fp); return '- System Error'; } $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0))); fseek($fp, $AddrSeek2); } else { fseek($fp, - 1, SEEK_CUR); } while (($char = fread($fp, 1)) != chr(0)) $ipAddr2 .= $char; $AddrSeek = implode('', unpack('L', $AddrSeek . chr(0))); fseek($fp, $AddrSeek); while (($char = fread($fp, 1)) != chr(0)) $ipAddr1 .= $char; } else { fseek($fp, - 1, SEEK_CUR); while (($char = fread($fp, 1)) != chr(0)) $ipAddr1 .= $char; $ipFlag = fread($fp, 1); if ($ipFlag == chr(2)) { $AddrSeek2 = fread($fp, 3); if (strlen($AddrSeek2) < 3) { fclose($fp); return '- System Error'; } $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0))); fseek($fp, $AddrSeek2); } else { fseek($fp, - 1, SEEK_CUR); } while (($char = fread($fp, 1)) != chr(0)) $ipAddr2 .= $char; } fclose($fp); if (preg_match('/http/i', $ipAddr2)) { $ipAddr2 = ''; } $ipaddr = "$ipAddr1 $ipAddr2"; $ipaddr = preg_replace('/CZ88\.NET/is', '', $ipaddr); $ipaddr = preg_replace('/^\s*/is', '', $ipaddr); $ipaddr = preg_replace('/\s*$/is', '', $ipaddr); if (preg_match('/http/i', $ipaddr) || $ipaddr == '') { $ipaddr = '- Unknown'; } $ipaddr = mb_convert_encoding($ipaddr, 'utf-8', 'GBK'); return $ipaddr; } function __destruct() { fclose($this->fp); } }
下载:QQIp.php