判断一个IP是否归属于中国
生活随笔
收集整理的這篇文章主要介紹了
判断一个IP是否归属于中国
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
業(yè)務(wù)的要求
- 判斷一個IP是不是屬于中國的
- 時間復(fù)雜度盡量小,適用于請求量大的業(yè)務(wù)場景
- 不要請求第三方接口,防止出現(xiàn)網(wǎng)絡(luò)異常
由于只需要判斷到國家的緯度,所以不需要用到純真IP庫這樣龐大的IP庫,通過網(wǎng)上的查詢,發(fā)現(xiàn)有個中國IP段的列表
http://ipblock.chacuo.net/down/t_txt=c_CN
可以看到IP段有2K個左右,如果用二分查詢法,時間復(fù)雜度是logN。基本上能夠滿足需求了。
實現(xiàn)步驟
一、 整理IP段配置
為了方便IP進行比較,這里將IP轉(zhuǎn)換為long格式。
最終得到的結(jié)果,如下:
<?php #部分數(shù)據(jù) array (0 => array ('left' => '16777472','right' => '16778239',),1 => array ('left' => '16779264','right' => '16781311',),2 => array ('left' => '16785408','right' => '16793599',),3 => array ('left' => '16842752','right' => '16843007',),4 => array ('left' => '16843264','right' => '16859135',) );二、二分查找法
function binarySearch(Array $arr, $target) {$low = 0;$high = count($arr) - 1;while($low <= $high) {$mid = floor(($low + $high) / 2);#找到元素if($target>=$arr[$mid]['left'] && $target<=$arr[$mid]['right']){return true;}#中元素比目標(biāo)大,查找左部if($target < $arr[$mid]['left'] ){$high = $mid - 1;}#中元素比目標(biāo)小,查找右部if($target > $arr[$mid]['left'] ){$low = $mid + 1;}}#查找失敗return false; }bitmap算法是否可行?
ip地址轉(zhuǎn)為long的最大值剛好是2^32-1 ,那么在redis中我們剛好可以申請一個4294967295的bitmap,占用內(nèi)存為512M。
如果能夠把所有中國的IP對應(yīng)的long都設(shè)置為1,那么每次查詢都只要0(1),遇到的問題是redis的setbit怎么批量設(shè)置呢?如果要一個ip設(shè)置一次的話,需要設(shè)置3億次,這個比較難實現(xiàn)。。
轉(zhuǎn)載于:https://www.cnblogs.com/zhidan/p/7562775.html
總結(jié)
以上是生活随笔為你收集整理的判断一个IP是否归属于中国的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数组字典树模板
- 下一篇: [BZOJ1643][Usaco2007