5

I am trying to query a bittorrent tracker and am using unpack to get the list of IPs from the response. So, something like this:

$ip = unpack("N", $peers);
$ip_add = ($ip[1]>>24) . "." . (($ip[1]&0x00FF0000)>>16) . "." . (($ip[1]&0x0000FF00)>>8) . "." . ($ip[1]&0x000000FF);

But, for some reason, I am getting the following IP addresses when I print $ip_add:

117.254.136.66
121.219.20.250
-43.7.52.163

Does anyone know what could be going wrong?

Charles
  • 50,943
  • 13
  • 104
  • 142
Legend
  • 113,822
  • 119
  • 272
  • 400

3 Answers3

10

use long2ip() to transform number back into ip

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • You are a savior! Thanks a lot. Cannot accept as answer within 10 mins of posting :)In any case, could you tell me what was going wrong with my method? – Legend Apr 16 '10 at 04:08
  • you have to add 2^31 to $ip before calculations ($ip + pow(2, 31)) – zerkms Apr 16 '10 at 04:15
5

As zerkms says, long2ip does what you want. To answer your question, >> is an arithmetic right shift (so named because $i >> $j is equivalent to the arithmetic expression i / 2j), which propagates the sign bit to preserve the sign of the number. That is, $i < 0 iff ($i >> $j) < 0. PHP doesn't have a logical shift (but you could define your own).

Community
  • 1
  • 1
outis
  • 75,655
  • 22
  • 151
  • 221
  • I see... Understood. Thanks for the explanation. Will go through the info you've provided. +1 Appreciate it. – Legend Apr 16 '10 at 04:12
1

Try this

function decode_ip($str){
    $str = (float)($str);
    $ip = array(
        (int)($str/pow(2,24)),
        (int)($str/pow(2,16) & 0xFF),
        (int)($str/pow(2,8) & 0xFF),
        (int)($str & 0xFF)
    );
    return join(".", $ip);
}

decode_ip("3225422716"); //192.64.11.124

Vitim.us
  • 20,746
  • 15
  • 92
  • 109