Nikk
Nikk

Reputation: 7891

PHP's inet_pton() to Convert both IPv4 and IPv6

When I use inet_pton() for FE80:0000:0000:0000:0202:B3FF:FE1E:8329 I get ������) whatever that is.

So then I added bin2hex() and get this fe800000000000000202b3fffe1e8329 better.

However, I was expecting a string of 16 not 32.

And it gets even more inconsistent from there.

When converting 8.8.8.8 I get 08080808 string of 8.


Is there a way to achieve some consistency where everything is the same length or should I add this to the database as is?

Am looking for an efficient/fast way to accomplish this that will result in a smaller string which would take less space on my database, without too many resources being wasted at it.

Upvotes: 2

Views: 1070

Answers (2)

IMSoP
IMSoP

Reputation: 97718

An IPv6 address is 128 bits long; an IPv4 address is 32 bits long.

This is no accident: one of the key motivations for creating IPv6 was that there are not enough possible 32-bit addresses for the needs of the modern internet.

������) whatever that is.

That is 128 bits, or 16 bytes, of binary data. Attempting to view it as text won't give you anything very interesting, because not every combination of bits is a displayable character.

So then I added bin2hex() and get this fe800000000000000202b3fffe1e8329

Converting the binary string to hexadecimal means representing each set of 4 bits as a character from the set 0123456789abcdef. The result is a string which is human readable, but 32 characters long (128 / 4 = 32).

You might notice that the standard way of writing an IPv6 address is just this string with a : added every 4 characters for readability.

When converting 8.8.8.8 I get 08080808

In binary, an IPv4 address would be 32 bits, or 4 bytes, long; but again, those wouldn't all be printable characters. As hexadecimal, it is a string 8 characters long, because that is how many sets of 4 bits it contains (32 / 4 = 8).

Is there a way to achieve some consistency where everything is the same length

The only way to make IPv4 addresses and IPv6 addresses the same length is to pad the IPv4 addresses with something on the left. It's like saying "can I make John's name take up the same space as Samantha's".

Am looking for an efficient/fast way to accomplish this that will result in a smaller string which would take less space on my database

The shortest universal representation is the binary one you got from inet_pton in the first place; just make sure to store it in a binary column in your database, not VarChar/Text/etc.

Alternatively, the standard text format for IPv6 has a short-hand where one sequence of 0s in an address can be replaced by ::, so FE80:0000:0000:0000:0202:B3FF:FE1E:8329 can be abbreviated FE80::0202:B3FF:FE1E:8329. I don't know of a PHP function for making such abbreviations, but it wouldn't be too hard to write one.

If you need it to be human-readable but short, you could play with other human-readable encodings of binary, like Base64 (which is natively supported by PHP). A character in base64 represents 6 bits, but the string is conventionally padded to be a multiple of both 8 and 6 bits long, so an IPv6 address will take up 24 printable characters (128 bits + 16 bits padding / 6 = 24).

Other rarer encodings are possible, such as "Base85", which use a wider range of characters to make the output shorter. However, they're all mathematically guaranteed to be longer than the binary representation, so you'll always need at least 16 bytes.

Upvotes: 6

user3668976
user3668976

Reputation: 76

In my opinion you should save them as they since these both are 2 different things. Even if both are designed for the same purpose.

Still if you want to get these both along you would most Likely take these actions : * calculate the decimal value of the ipv6 since it's hexadecimal or the other way around. * ipv6 is 2^128 and ipv4 is 2^32. You need to calculate the differences to have the same base on both sides. This could be accomplished with placeholders (zeros at the start as example) until you have the same Potency *You now could save them as even strings in the databases.

I sadly can't give examples since I'm on my mobile phone. But I think it should be clear.

Upvotes: 0

Related Questions