PHP的inet_pton()转换IPv4和IPv6

Bor*_*rsn 2 php

当我使用时inet_pton(),FE80:0000:0000:0000:0202:B3FF:FE1E:8329我得到??????)任何东西.

所以我添加bin2hex()fe800000000000000202b3fffe1e8329更好地完成了.

但是,我期待一个16而不是32的字符串.

而且从那里变得更加不一致.

转换时,8.8.8.8我得到080808088的字符串.


有没有办法在一切都相同的长度上实现某种一致性,还是应该按原样将其添加到数据库中?

我正在寻找一种有效/快速的方法来实现这一目标,这将导致一个更小的字符串,这将占用我的数据库更少的空间,而不会浪费太多的资源.

IMS*_*SoP 6

IPv6地址长128位; IPv4地址长度为32位.

这不是偶然的:创建IPv6的关键动机之一是没有足够的32位地址来满足现代互联网的需求.

??????) 无论那是什么.

这是128位或16字节的二进制数据.试图将其视为文本不会给你带来任何有趣的东西,因为并非每个位组合都是可显示的字符.

所以我添加bin2hex()并得到了这个fe800000000000000202b3fffe1e8329

将二进制字符串转换为十六进制表示将每组4位表示为集合中的字符0123456789abcdef.结果是一个人类可读的字符串,但长度为32个字符(128/4 = 32).

您可能会注意到,编写IPv6地址的标准方法就是此字符串,:每4个字符添加一次以提高可读性.

当转换8.8.8.8时,我得到08080808

在二进制中,IPv4地址将是32位,或4字节,长; 但同样,那些不会都是可打印的角色.作为十六进制,它是一个长度为8个字符的字符串,因为它包含多少组4位(32/4 = 8).

有没有办法在一切都长度相同的情况下实现某种一致性

使IPv4地址和IPv6地址长度相同的唯一方法是在左侧填充IPv4地址.这就像说"我可以让约翰的名字占据与萨曼莎相同的空间".

我正在寻找一种有效/快速的方法来实现这一目标,这将导致更小的字符串,这将占用我的数据库更少的空间

最短的通用表示是你从一开始就得到的二进制表示inet_pton; 只需确保将其存储在数据库的二进制列中,而不是VarChar/ Text/ etc.

或者,IPv6的标准文本格式有一个简写,其中地址中的一个0序列可以替换为::,因此FE80:0000:0000:0000:0202:B3FF:FE1E:8329可以缩写FE80::0202:B3FF:FE1E:8329.我不知道用于制作这种缩写的PHP函数,但写一个也不会太难.

如果你需要它是人类可读但很短,你可以使用其他人类可读的二进制编码,如Base64(PHP本身支持).base64中的字符表示6位,但字符串通常填充为8位和6位长的倍数,因此IPv6地址将占用24个可打印字符(128位+ 16位填充/ 6 = 24).

其他更罕见的编码也是可能的,例如" Base85 ",它使用更广泛的字符来缩短输出.但是,它们在数学上都保证比二进制表示更长,因此您总是需要至少16个字节.