From: Andrew Ballard on
On Wed, Jun 23, 2010 at 6:01 AM, Ashley Sheridan
<ash(a)ashleysheridan.co.uk> wrote:
> That's what I'd use. You may also have to wrap it inside an abs() call
> to ensure it's a positive number, as some IP addresses equate to
> negative with ip2long().

NO NO NO NO NO!!!!

<?php

$x = ip2long('192.168.0.1');
var_dump($x);
// int(-1062731775)

var_dump(long2ip($x));
// string(11) "192.168.0.1"

var_dump(long2ip(abs($x)));
// string(13) "63.87.255.255"

?>

Andrew
From: Ashley Sheridan on
On Wed, 2010-06-23 at 10:35 -0400, Andrew Ballard wrote:

> On Wed, Jun 23, 2010 at 6:01 AM, Ashley Sheridan
> <ash(a)ashleysheridan.co.uk> wrote:
> > That's what I'd use. You may also have to wrap it inside an abs() call
> > to ensure it's a positive number, as some IP addresses equate to
> > negative with ip2long().
>
> NO NO NO NO NO!!!!
>
> <?php
>
> $x = ip2long('192.168.0.1');
> var_dump($x);
> // int(-1062731775)
>
> var_dump(long2ip($x));
> // string(11) "192.168.0.1"
>
> var_dump(long2ip(abs($x)));
> // string(13) "63.87.255.255"
>
> ?>
>
> Andrew
>

Someone had better tell all the makers of the ip2country databases then,
because there's not a negative number in sight!

Thanks,
Ash
http://www.ashleysheridan.co.uk


From: Andrew Ballard on
On Wed, Jun 23, 2010 at 10:39 AM, Ashley Sheridan
<ash(a)ashleysheridan.co.uk> wrote:
>
> On Wed, 2010-06-23 at 10:35 -0400, Andrew Ballard wrote:
>
> On Wed, Jun 23, 2010 at 6:01 AM, Ashley Sheridan
> <ash(a)ashleysheridan.co.uk> wrote:
> > That's what I'd use. You may also have to wrap it inside an abs() call
> > to ensure it's a positive number, as some IP addresses equate to
> > negative with ip2long().
>
> NO NO NO NO NO!!!!
>
> <?php
>
> $x = ip2long('192.168.0.1');
> var_dump($x);
> // int(-1062731775)
>
> var_dump(long2ip($x));
> // string(11) "192.168.0.1"
>
> var_dump(long2ip(abs($x)));
> // string(13) "63.87.255.255"
>
> ?>
>
> Andrew
>
> Someone had better tell all the makers of the ip2country databases then, because there's not a negative number in sight!
>
> Thanks,
> Ash
> http://www.ashleysheridan.co.uk
>
>

You might choose to store an 8-byte integer rather than a 4-byte
integer to prevent negative numbers, but abs() won't do that. Usually
when I store IPv4 addresses in a database, I store them as BINARY(4)
so that I can compare ranges without worrying about either handling
negative numbers or using 8 bytes of storage to deal with addresses
above 127.255.255.255. I have also seen people present a case for
storing each octet in a separate TINYINT column.

Andrew
From: Ashley Sheridan on
On Wed, 2010-06-23 at 10:58 -0400, Andrew Ballard wrote:

> On Wed, Jun 23, 2010 at 10:39 AM, Ashley Sheridan
> <ash(a)ashleysheridan.co.uk> wrote:
> >
> > On Wed, 2010-06-23 at 10:35 -0400, Andrew Ballard wrote:
> >
> > On Wed, Jun 23, 2010 at 6:01 AM, Ashley Sheridan
> > <ash(a)ashleysheridan.co.uk> wrote:
> > > That's what I'd use. You may also have to wrap it inside an abs() call
> > > to ensure it's a positive number, as some IP addresses equate to
> > > negative with ip2long().
> >
> > NO NO NO NO NO!!!!
> >
> > <?php
> >
> > $x = ip2long('192.168.0.1');
> > var_dump($x);
> > // int(-1062731775)
> >
> > var_dump(long2ip($x));
> > // string(11) "192.168.0.1"
> >
> > var_dump(long2ip(abs($x)));
> > // string(13) "63.87.255.255"
> >
> > ?>
> >
> > Andrew
> >
> > Someone had better tell all the makers of the ip2country databases then, because there's not a negative number in sight!
> >
> > Thanks,
> > Ash
> > http://www.ashleysheridan.co.uk
> >
> >
>
> You might choose to store an 8-byte integer rather than a 4-byte
> integer to prevent negative numbers, but abs() won't do that. Usually
> when I store IPv4 addresses in a database, I store them as BINARY(4)
> so that I can compare ranges without worrying about either handling
> negative numbers or using 8 bytes of storage to deal with addresses
> above 127.255.255.255. I have also seen people present a case for
> storing each octet in a separate TINYINT column.
>
> Andrew
>


Out of interest, how does PHP calculate the IP number, as it was my
understanding of IP numbers that they can't be negative.

For example, my IP address is 89.243.156.135
The four parts as binary:
01011001
11110011
10011100
10000111

>From there, I thought that the binary values were concatenated as if
they were a string, and then the decimal value worked out from that,
giving, in my case, a value of 1509137543.

How is it possible that PHP can produce negative values from this
method? Does it do something else entirely, or is this a case of the
integer value overflowing into negative values? (which might explain why
the value correctly converts back)

If so, what would be the best method to get the correct value, as abs()
obviously isn't it!

Thanks,
Ash
http://www.ashleysheridan.co.uk


From: "Bob McConnell" on
From: Ashley Sheridan

> Out of interest, how does PHP calculate the IP number, as it was my
> understanding of IP numbers that they can't be negative.
>
> For example, my IP address is 89.243.156.135
> The four parts as binary:
> 01011001
> 11110011
> 10011100
> 10000111
>
> >From there, I thought that the binary values were concatenated as if
> they were a string, and then the decimal value worked out from that,
> giving, in my case, a value of 1509137543.
>
> How is it possible that PHP can produce negative values from this
> method? Does it do something else entirely, or is this a case of the
> integer value overflowing into negative values? (which might explain
why
> the value correctly converts back)

When stored as a four byte integer, the high bit becomes the sign flag.
So if the first byte is 128 or higher, it would be converted into a
negative number.

This is a common issue when the size of numbers exceed the storage space
allotted. It's well understood in tightly typed languages, but often
missed in the more loosely typed languages like Perl and PHP.

Bob McConnell