先上代码了. 它最原始的出处,应该是DZ!最近看的自家的老项目中也有这样一段.
本人不才, 一段一段的分析, 目前发现有个地方实在无法理解: if($ipbegin < 0) $ipbegin += pow(2, 32); // 什么情况下,$ipbegin<0 呢 ???
还有一个问题就是:这个函数引用了一个qqwry.dat(刚开始差点写成bat).这个文件的原始出处在哪里呢,比如官网,和文档说明,如何用之类的信息 ?
查了百度百科, 只有简短的介绍, 还是找不到我想要的答案.
public function qqwry($ip='222.222.222.222'){
//$fd->resource(24, stream)
if(!$fd = @fopen("./Public/qqwry.dat", 'rb')) {
return 'Invalid IP data file';
}
$ip = explode('.', $ip);
//$ipNum=2079656996
$ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
//获取IP地址索引开始和结束位置, 此时两个变量输出是乱码(应该是二进制的原因)
if(!($DataBegin = fread($fd, 4)) || !($DataEnd = fread($fd, 4)) ){
return;
}
// unpack() 函数从二进制字符串对数据进行解包,L--无符号长整数
// implode — Join array elements with(以) a string
@$ipbegin = implode('', unpack('L', $DataBegin));// 6153398
//pow(x,y)--pow() 函数返回 x 的 y 次方。
if($ipbegin < 0) $ipbegin += pow(2, 32); // 什么情况下,$ipbegin<0 呢 ???
// implode — Join array elements with(以) a string
@$ipend = implode('', unpack('L', $DataEnd));
if($ipend < 0) $ipend += pow(2, 32);
$ipAllNum = ($ipend - $ipbegin) / 7 + 1;
$BeginNum = $ip2num = $ip1num = 0;
$ipAddr1 = $ipAddr2 = '';
$EndNum = $ipAllNum;
while($ip1num > $ipNum || $ip2num < $ipNum) {
//下面是一大段二分法, 就不复制了
IP is expressed in binary as 32bit, so int is also 32bit. Use numbers to store IP, which has better search efficiency and storage space
int represents positive and negative. So it’s normal to have negative numbers