php二分法读取IP库文件

/*
二分法,查询IP文件
本文目的在于学习到fseek的使用方法和二分法原理

ip.csv文件格式
16908288,16908799,中国,福建省,未知
16908800,16909055,中国,北京市,北京市
16909312,16910335,中国,福建省,未知


1,2,3,4,5,6,7,8,9,10,11,12,13,14

3

mid = mid/2 = 7

$mid = $mid/2 = 4;

$mid = $mid/2 = 2;

$mid =

要求该文件,必须数字从小到大排列,否则无法采用二分法。

原理

1.得到文件大小703
2.折半对比IP数字大小,小于的,向前折半,大于的向后折半查找


header('Content-Type: text/html; charset=gbk');

$stime = time();

$ip = "124.58.180.5";





$address = readip($ip);



echo $address;



function readip($ip){

	$ip_num = $ip_n = bindec(decbin(ip2long($ip)));

	

	echo $ip_num;

	

	$fname = 'ipfull.csv';

	

	$fd = @fopen($fname, 'rb');

	$size = filesize($fname);//得到文件大小,才好采用二分法

	echo ' - size is : ';

	echo $size;

	echo '
 
 
'; $len = $size; $adress = ''; $sm = 0; $em = $size; $mid = ceil(($em - $sm)/2); $b = true; $ci = 0; //走的次数 while($b){ echo "$sm , $em , ".$mid.' - '; fseek($fd,$mid); $line = fread($fd, 80); $x = explode("\n",$line); $qline = $line; $line = ''; foreach($x as $k=>$v){ if(preg_match("/^\\d+,\\d+,.*?,.*?,.*?$/",$v)){ $line = $v; } } if($line==''){//最后的处理,直接命中 fseek($fd,$sm); $line = fread($fd,$size-$mid); $x = explode("\n",$line); foreach($x as $k=>$v){ if(preg_match("/^\\d{8,10},\\d{8,10},.*?,.*?,.*?/",$v)){ $line = $v; $arr = explode(',',$line); $start = intval($arr[0]); $end = intval($arr[1]); if($ip_num >= $start && $ip_num <= $end){ echo '命中'.$line; $address = $arr[2].$arr[3].$arr[4]; return $address; $b = false; break; } } } break; } $arr = explode(',',$line); $start = $arr[0]; $end = $arr[1]; if($ip_num < $start ){ echo '向前走'; $em = $mid; $mid = $sm + ceil(($em - $sm)/2); } if( $ip_num > $end){ echo '向后走'." # $start @ $end #"; $sm = $mid; $mid = $mid + ceil(($em - $sm)/2); } if($ip_num >= $start && $ip_num <= $end){ echo '命中'; $address = $arr[2].$arr[3].$arr[4]; $b = false; } echo ' -- '; echo $line; echo ' '; if($mid<2)$b = false; if($ci>100) $b = false;//说明没有找到 $ci++; } $etime = time(); $utime = $etime - $stime; echo $address; echo 'use time.'.$utime; return $address; }


经过测试这个方法,只需要1毫秒,即可查找到对应的IP地理位置
首发于 http://java-er.com/blog/php-ip-address/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值