Detail method for converting IP address to real address

  • 2020-06-12 08:34:46
  • OfStack

Want to IPv4 address into real address, must be the reference IP database, commercial IP stored in relational database, the database query and use is very convenient, but the cost is not individual and small willing to bear, so the application of simple idea is to use some free IP database or 1 big website provides query API, they the amount of data we use enough.
1. Use the Pure IP database
Using the local QQWry.Dat file, the advantage is that the query is very fast, but the disadvantage is that the database files have to be kept in their own space and the database has to be updated occasionally. If you are using WordPress, write the following code to functions.php under the topic, and then output in ES13en-ES14en < ?php echo convertip(get_comment_author_ip()); ? > Can; If it is another program reference, enter a valid IPv4 address to get a real address.

function convertip($ip) {
    //IP Data file path 
    $dat_path = 'QQWry.Dat';
    // check IP address 
    //if(!preg_match("/^d{1,3}.d{1,3}.d{1,3}.d{1,3}$/", $ip)) {
    //    return 'IP Address Error';
    //}
    // Open the IP The data file 
    if(!$fd = @fopen($dat_path, 'rb')){
        return 'IP date file not exists or access denied';
    }
    // decomposition IP You do the operation and you get the number of shadings 
    $ip = explode('.', $ip);
    $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
    // To obtain IP Data index start and end locations 
    $DataBegin = fread($fd, 4);
    $DataEnd = fread($fd, 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;
    // use 2 Fractional lookup searches for a match from an index record IP record 
    while($ip1num>$ipNum || $ip2num<$ipNum) {
        $Middle= intval(($EndNum + $BeginNum) / 2);
        // Offset pointer read to index position 4 bytes 
        fseek($fd, $ipbegin + 7 * $Middle);
        $ipData1 = fread($fd, 4);
        if(strlen($ipData1) < 4) {
            fclose($fd);
            return 'System Error';
        }
        // Extract the data transformation growth plastic, if the data is negative then add 2 the 32 power 
        $ip1num = implode('', unpack('L', $ipData1));
        if($ip1num < 0) $ip1num += pow(2, 32);
        // The number of long integers extracted is greater than ours IP The address will be modified at the end of the location 1 loops 
        if($ip1num > $ipNum) {
            $EndNum = $Middle;
            continue;
        }
        // Take on the 1 Index and then pull down 1 index 
        $DataSeek = fread($fd, 3);
        if(strlen($DataSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
        fseek($fd, $DataSeek);
        $ipData2 = fread($fd, 4);
        if(strlen($ipData2) < 4) {
            fclose($fd);
            return 'System Error';
        }
        $ip2num = implode('', unpack('L', $ipData2));
        if($ip2num < 0) $ip2num += pow(2, 32);
        // No prompt unknown found 
        if($ip2num < $ipNum) {
            if($Middle == $BeginNum) {
                fclose($fd);
                return 'Unknown';
            }
            $BeginNum = $Middle;
        }
    }
    $ipFlag = fread($fd, 1);
    if($ipFlag == chr(1)) {
        $ipSeek = fread($fd, 3);
        if(strlen($ipSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
        fseek($fd, $ipSeek);
        $ipFlag = fread($fd, 1);
    }
    if($ipFlag == chr(2)) {
        $AddrSeek = fread($fd, 3);
        if(strlen($AddrSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0))
            $ipAddr2 .= $char;
        $AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
        fseek($fd, $AddrSeek);
        while(($char = fread($fd, 1)) != chr(0))
            $ipAddr1 .= $char;
    } else {
        fseek($fd, -1, SEEK_CUR);
        while(($char = fread($fd, 1)) != chr(0))
            $ipAddr1 .= $char;
        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0)){
            $ipAddr2 .= $char;
        }
    }
    fclose($fd);
    // The result is returned after the appropriate replacement 
    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 = iconv('gbk', 'utf-8//IGNORE', $ipaddr); // Convert the code if the web page gbk You can delete this line 
    return $ipaddr;
}

2. Use the portal interface
At present, it is known that Tencent, sina, netease, sohu and Google provide IP address query, but only Tencent, sina and netease can be found, and Google seems to use Google Maps, so there is no research. Check the domestic Tencent is provided with JavaScript, netease is provided with XML, and sina has a variety of formats can be used, note that non-XML data source is GBK format, whether it is JavaScript call or PHP call to convert 1 code, otherwise you will get a messy code. More importantly, if you query multiple IP at once, using API on the portal will be very slow. I probably wrote an for loop to try it out. Whether using PHP to parse XML or file_get_contents() to get the content, the query will be very slow and may even time out after 10 times.

Tencent's IP address API interface: http: / / fw qq. com/ipaddress, returns the data format for: var IPData = new Array (" 123.124.2.85 ", ""," Beijing ", ""); , an object of JavaScript, currently do not know how to enter IP query.
Sina IP address query interface: http: / / int dpool. sina. com. cn/iplookup/iplookup php? format = js
Sina more regional test method: http: / / int dpool. sina. com. cn/iplookup/iplookup php? format = js & ip=123.124.2.85
Netease youdao IP address query interface: http: / / www youdao. com/smartresult - xml/search s? type = ip & q=123.124.2.85
// Tencent API PHP call method

function getIpPlace(){
 $ip=file_get_contents("http://fw.qq.com/ipaddress");
 $ip=str_replace('"',' ',$ip);
 $ip2=explode("(",$ip);
 $a=substr($ip2[1],0,-2);
 $b=explode(",",$a);
 return $b;
}
$ip=getIpPlace();
print_r($ip);

// youdao API's PHP call method

$url = "http:www.youdao.com/smartresult-xml/search.s?type=ip&q=".$ip;
$doc = new DOMDocument();
   $doc->load($url);
   $smartresult = $doc->getElementsByTagName("product");
   foreach($smartresult as $product)
   {
      $locations = $product->getElementsByTagName("location");
      $location = $locations->item(0)->nodeValue;
   }
   if($location != "")
   {
       echo $i.".".$ip;
       echo "   from ".$location." The net friend ";
   }
   else
   {
       echo $i.".".$ip;
       echo "   From Mars ";
   }
public function sinaIPApi($ip){
   $str = file_get_contents("http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=".$ip);
   $str = iconv("gbk", "utf-8//IGNORE", $str);
   preg_match_all("/[/x{4e00}-/x{9fa5}]+/u",$str,$get);
   $add = implode('',$get[0]);
   return $add;
}
//$get is 1 It's a great one 2 Dimensional array 

The youdao and sina is written by myself, sina API also can use file_get_contents like tencent API after () function to obtain the address use 1 series of string processing, the function I wrote using regular expressions from sina return results provide string contains Chinese, and segmented into a 2 d array, this may only be useful for sina API bug and existence. For example, the $get variable in the function var_dump()1 gets the following result: array(1) {[0]= > array(6) { [0]= > string(6) "China" [1]= > string(6) "Beijing" [2]= > string(6) "Beijing" [3]= > string(9) "education network" [4]= > string(6) "school" [5]= > string(18) "China University of Geosciences", and the output of the function is "China Beijing Beijing Education Network school China University of Geosciences", I hope my ideas and methods can be useful to others.

Finally again, if is WordPress please use method 1, otherwise use API queries all at the same time the writer's real address will let PHP timeout, hope each and have a better method, as to limit the way of display and what are WordPress application problem, at the same time for C # and Java thought also is one kind of, the subsequent problems again after I test in detail.

Related articles: