当我将inet_pton()
用于FE80:0000:0000:0000:0202:B3FF:FE1E:8329
时,无论如何我都会得到������)
。
因此,我添加了bin2hex()
,并使它fe800000000000000202b3fffe1e8329
更好。
但是,我期望的是16而不是32的字符串。
从那里变得更加不一致。
转换8.8.8.8
时得到的08080808
字符串为8。
在所有长度都相同的情况下,是否可以实现某种一致性?还是应该将其原样添加到数据库中?
我正在寻找一种高效/快速的方法来实现这一点,从而产生一个较小的字符串,该字符串将占用我的数据库更少的空间,而不会浪费太多的资源。
答案 0 :(得分:6)
IPv6地址的长度为128位; IPv4地址的长度为32位。
这绝非偶然:创建IPv6的主要动机之一是没有足够的32位地址来满足现代Internet的需求。
������)
无关。
即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(即natively supported by PHP)。 base64中的一个字符代表6位,但是通常将字符串填充为8位和6位长的倍数,因此IPv6地址将占用24个可打印字符(128位+ 16位填充/ 6 = 24)。
其他更罕见的编码也是可能的,例如“ Base85”,它使用更大范围的字符来使输出更短。但是,从数学上讲,它们全部都比二进制表示法长,因此您始终至少需要16个字节。
答案 1 :(得分:0)
我认为您应该保存它们,因为它们都是2种不同的东西。即使两者都是出于相同目的而设计。
如果您想同时实现这两个目标,则最有可能采取以下行动: *计算ipv6的十进制值,因为它是十六进制或相反。 * ipv6为2 ^ 128,ipv4为2 ^ 32。您需要计算差异以使双方的底数相同。可以使用占位符(例如,开头为零)来完成此操作,直到您拥有相同的效价为止 *您现在可以将它们另存为数据库中的字符串。
可悲的是,由于我正在使用手机,因此我无法提供示例。但是我认为应该清楚。