我使用以下命令将IP地址存储在数据库中:

cast(INET6_ATON(trim(:ipbinary)) as binary(16)))

我的专栏是:
varbinary(16)

我试过使用mysql函数INET6_NTOA将其转换回IPv4格式,但是还没有运气。

我需要的IP是:
66.249.64.90

DB值是:
42f9405a000000000000000000000000
INET6_NTOA给我:
42f9:405a::
INET6_NTOA(UNHEX(给了我一个NULL响应。我使用PHP作为脚本语言,因此如果那里也有功能,我也可以使用它。

这是我的完整查询:
SELECT delete_ip, INET6_NTOA(ip_binary), ip_binary FROM `stats`

这是响应:

mysql - IP地址对人类可读的二进制-LMLPHP

谢谢。

(我不能只使用delete_ip,因为顾名思义,该列将被删除。)

最佳答案

它没有转换回IPv4可读格式,而是转换为IPv6,因为INET6_NTOA(二进制值)的参数为16个字节。

该功能将其视为IPv6地址的表示,而不是仅四个字节的IPv4地址。

我认为问题可以追溯到问题的第一行SQL,即强制转换为BINARY(16)。这将返回16字节的固定长度。从为IPv4地址返回的四个字节开始,然后在右边用零填充,直到16个字节的长度。

如果我们删除固定长度的转换,并允许INET6_ATON函数的结果仅为四个字节,会发生什么?

当数据库中存储的值只有四个字节时会发生什么?

如果我们更正了stats表的内容,将那个16字节的二进制值(IPv6地址的表示形式)更改为一个IPv4地址的四字节的二进制表示形式,该怎么办?

UPDATE `stats`
   SET ip_binary = INET6_ATON('66.249.64.90')
 WHERE ip_binary = CAST(INET6_ATON('66.249.64.90') AS BINARY(16))

- 或者 -
UPDATE `stats`
   SET ip_binary = X'42f9405a' + 0
 WHERE ip_binary = X'42f9405a000000000000000000000000' + 0

后续行动

问题说...“使用[表达式]在数据库[列]中存储IP地址,如下所示:
 cast(INET6_ATON(trim(:ipbinary)) as binary(16)))

我们不需要使用CAST。而且我们不需要使用CONVERTHEX/UNHEXSUBSTR。使用相同的表达式转换IPv4和IPv6地址:
  INSERT ... ip_binary ... VALUES ( ... , INET6_ATON( :ip_string ) , ...

并将它们转换回这样的字符串:
 SELECT ... , INET6_NTOA( ip_binary ) AS ip_string , ...

带有CASTCONVERTSUBSTRHEX/UNHEX的rigmarole令人困惑,并导致事情不起作用。

为了更正已经存储在数据库中的值,我们需要一种方法来区分16个字节的二进制表示形式中的哪一个实际上是应该存储为4个字节的IPv4地址。

如果ip_delete包含字符串表示形式,我们可以重新转换为二进制表示形式。
 UPDATE `stats`
    SET ip_binary = INET6_ATON( ip_delete )

示范
CREATE TABLE `addr` (ip_string VARCHAR(45), ip_binary VARBINARY(16)) ;

INSERT INTO `addr` VALUES ( '66.249.64.90'         , INET6_ATON( '66.249.64.90'         ));
INSERT INTO `addr` VALUES ( '127.0.0.1'            , INET6_ATON( '127.0.0.1'            ));
INSERT INTO `addr` VALUES ( '192.168.1.1'          , INET6_ATON( '192.168.0.1'          ));
INSERT INTO `addr` VALUES ( '2001:4860:4860::8888' , INET6_ATON( '2001:4860:4860::8888' ));

SELECT ip_string, HEX(ip_binary), INET6_NTOA(ip_binary) FROM `addr` ;

ip_string             HEX(ip_binary)                    INET6_NTOA(ip_binary)
--------------------  --------------------------------  -----------------------
66.249.64.90          42F9405A                          66.249.64.90
127.0.0.1             7F000001                          127.0.0.1
192.168.1.1           C0A80001                          192.168.0.1
2001:4860:4860::8888  20014860486000000000000000008888  2001:4860:4860::8888

10-08 13:43
查看更多