您的位置 首页 php

PHP/Python 二分查找法获取IP地理位置

最近今日头条上线了在创作者个人主页“更多信息”里显示创作者的地理位置。今日头条是为了加强建设健康、优质、有益、多元的网络生态。但功能上线后曝光了一些人性虚伪的层面。有些V账号的个人主页的地理位置与创作内容说的地理位置不同。让大众着实笑笑解千仇了一下。今天为大家介绍PHP/Python两种编程语言利用二分查找法获取IP地理位置。功能考虑IP段和指定IP两种情况的地理位置处理。

一、PHP二分查找法获取IP地理位置

1、PHP获取用户客户端IP地址

 <?php
function getClientIp() {
$strUip = '';
if (isset($_SERVER['HTTP_X_BD_USERIP']) && $_SERVER['HTTP_X_BD_USERIP'] && strcasecmp($_SERVER['HTTP_X_BD_USERIP'], 'unknown')) {
            $strUip = $_SERVER['HTTP_X_BD_USERIP'];
        } else if (!empty($_SERVER['HTTP_CLIENTIP6'])) {
            $strUip = $_SERVER['HTTP_CLIENTIP6'];
        } else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], 'unknown')) {
            $strUip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            strpos($strUip, ',') && list($strUip) = explode(',', $strUip);
        } else if (!empty($_SERVER['HTTP_CLIENT_IP']) && strcasecmp($_SERVER['HTTP_CLIENT_IP'], 'unknown')) {
            $strUip = $_SERVER['HTTP_CLIENT_IP'];
        } else if (!empty($_SERVER['REMOTE_ADDR']) && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $strUip = $_SERVER['REMOTE_ADDR'];
        }
        
        return $strUip;
}

$strUip = getClientIp();
var_dump($strUip);
执行结果:
string(15) "183.199.168.188"  

2、PHP二分查找法获取IP地理位置

 <?php
function search_ip_addr_recursion($arrIp, $intLow, $intHigh, $intIp) {
  $intMiddle = intval(($intLow + $intHigh) / 2);
  if ($intLow > $intHigh) {
        return -1;
  }
  //处理指定ip逻辑
  if (isset($arrIp[$intMiddle]['ip'])) {
    $intMiddleIp = ip2long($arrIp[$intMiddle]['ip']);
  } else {
    //处理ip段逻辑
    $intMiddleStartIp = ip2long($arrIp[$intMiddle]['range']['s']);
    $intMiddleEndIp = ip2long($arrIp[$intMiddle]['range']['e']);
  }
  if (isset($intMiddleIp) && $intMiddleIp == $intIp) {
    return $intMiddle;
  }
  if (isset($intMiddleStartIp) && $intIp >= $intMiddleStartIp && $intIp <= $intMiddleEndIp) {
    return $intMiddle;
  }
  //处理指定ip逻辑
  if (isset($intMiddleIp) && $intIp > $intMiddleIp) {
    return search_ip_addr_recursion($arrIp, $intMiddle + 1, $intHigh, $intIp);
  } elseif (isset($intMiddleIp) && $intIp < $intMiddleIp) {
    return search_ip_addr_recursion($arrIp, $intLow, $intMiddle - 1, $intIp);
  }
  //处理ip段逻辑
  if (isset($intMiddleEndIp) && $intIp > $intMiddleEndIp) {
    return search_ip_addr_recursion($arrIp, $intMiddle + 1, $intHigh, $intIp);
  } elseif (isset($intMiddleEndIp) && $intIp < $intMiddleEndIp) {
    return search_ip_addr_recursion($arrIp, $intLow, $intMiddle - 1, $intIp);
  }
  //if代码是一条垂线下来
}

//ip测试
$arrIp = array(
  array('ip' => '202.132.13.12', 'addr' => '北京'),
  array('range' => array('s' => '212.12.24.12', 'e' => '212.13.25.14'), 'addr' => '山西'),
  array('range' => array('s' => '212.13.25.15', 'e' => '212.15.25.14'), 'addr' => '河北'),
);
$intIp = ip2long('212.12.24.13');
//$intIp = ip2long('202.132.13.12');
$intIndex = search_ip_addr_recursion($arrIp, 0, count($arrIp), $intIp);
var_dump($intIndex);
if (-1 === $intIndex) {
  var_dump('None');
} else {
  var_dump($arrIp[$intIndex]);
}
执行结果:
int(1)
array(2) {
  ["range"]=>
  array(2) {
    ["s"]=>
    string(12) "212.12.24.12"
    ["e"]=>
    string(12) "212.13.25.14"
  }
  ["addr"]=>
  string(6) "山西"
}  

二、Python二分查找法获取IP地理位置

1、Python获取用户客户端IP地址

 import requests

def getClientIp(res):
    strUip = '';
    if res.headers.get('HTTP_CLIENTIP6') is not None:
        strUip = res.headers.get('HTTP_CLIENTIP6')
    elif res.headers.get('HTTP_X_FORWARDED_FOR') is not None and res.headers.get('HTTP_X_FORWARDED_FOR') != 'unknown':
        strUip = res.headers.get('HTTP_X_FORWARDED_FOR')
    elif res.headers.get('HTTP_CLIENT_IP') is not None and res.headers.get('HTTP_CLIENT_IP') != 'unknown':
        strUip = res.headers.get('HTTP_CLIENT_IP')
    elif res.headers.get('REMOTE_ADDR') is not None and res.headers.get('REMOTE_ADDR') != 'unknown':
        strUip = res.headers.get('REMOTE_ADDR')
    elif res.headers.get('HTTP_X_BD_USERIP') and res.headers.get('HTTP_X_BD_USERIP') != 'unknown':
        strUip = res.headers.get('HTTP_X_BD_USERIP')

    return strUip;

res = requests.get('#39;)

strUip = getClientIp(res);
print(strUip);
执行结果:
183.199.168.188  

2、Python二分查找法获取IP地理位置

 import socket, struct

def isset(arr, key):
try:
type(arr[key])
except:
return False
return True

def ip2long(strIp):
return struct.unpack("!L", socket.inet_aton(strIp))[0]

def search_ip_addr_recursion(arrIp, intLow, intHigh, intIp):
  intMiddle = int((intLow + intHigh) / 2)
  if intLow > intHigh:
        return -1
  if isset(arrIp[intMiddle], 'ip'):
    intMiddleIp = ip2long(arrIp[intMiddle]['ip'])
    if intMiddleIp == intIp:
        return intMiddle
    if intIp > intMiddleIp:
        return search_ip_addr_recursion(arrIp, intMiddle + 1, intHigh, intIp)
    elif intIp < intMiddleIp:
        return search_ip_addr_recursion(arrIp, intLow, intMiddle - 1, intIp)
  else:
    intMiddleStartIp = ip2long(arrIp[intMiddle]['range']['s'])
    intMiddleEndIp = ip2long(arrIp[intMiddle]['range']['e'])
    if intIp >= intMiddleStartIp and intIp <= intMiddleEndIp:
        return intMiddle
    if intIp > intMiddleEndIp:
        return search_ip_addr_recursion(arrIp, intMiddle + 1, intHigh, intIp)
    elif intIp < intMiddleEndIp:
        return search_ip_addr_recursion(arrIp, intLow, intMiddle - 1, intIp)

arrIp = [ 
  {'ip': '202.132.13.12', 'addr':'北京'},
  {'range': {'s': '212.12.24.12', 'e': '212.13.25.14'}, 'addr': '山西'},
  {'range': {'s': '212.13.25.15', 'e': '212.15.25.14'}, 'addr': '河北'},
]
intIp = ip2long('212.12.24.13');
#intIp = ip2long('202.132.13.12');
intIndex = search_ip_addr_recursion(arrIp, 0, len(arrIp), intIp);
print(intIndex)
if -1 == intIndex:
  print('None')
else:
  print(arrIp[intIndex])
执行结果:
1
{'range': {'s': '212.12.24.12', 'e': '212.13.25.14'}, 'addr': '山西'}  

三、总结

  • Python的代码是根据PHP代码平移过来的。PHP函数用Python函数替换或def定义。语言语法按标准替换就行。
  • 查找方法需要将ip段按从小到大排好顺序可以写入内存中减少不必要的查询。
  • 头条有定义“I P属地以运营商信息为准,境内显示到省(区、市),境外显示到国家(地区) ”。表示IP需要实时或定时的与运营商IP信息同步。数据上可能存在时差的情况。
  • IP信息的定义可以更丰富更全个人只是测试代码用。

大家有什么更好的解决方案或算法可以发评论沟通。业务上都是调别人的接口像百度都是调用百度地图的开放API接口。

Go语言的等我把Golang学的再深入一点再介绍给大家[呲牙]。

文章来源:智云一二三科技

文章标题:PHP/Python 二分查找法获取IP地理位置

文章地址:https://www.zhihuclub.com/78526.shtml

关于作者: 智云科技

热门文章

网站地图