我使用如下命令存储在数据库中的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`
以及回复:
感谢。
(我不能只使用delete_ip
,因为顾名思义该列将被删除。)
答案 0 :(得分:2)
它不会转换回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
。我们无需使用CONVERT
,HEX
/ UNHEX
或SUBSTR
。使用相同的表达式转换IPv4和IPv6地址:
INSERT ... ip_binary ... VALUES ( ... , INET6_ATON( :ip_string ) , ...
然后将它们转换回这样的字符串:
SELECT ... , INET6_NTOA( ip_binary ) AS ip_string , ...
CAST
,CONVERT
,SUBSTR
,HEX
/ UNHEX
的严重错误令人困惑,导致事情无效。
要纠正已存储在数据库中的值,我们需要一种方法来区分哪个16字节二进制表示实际上是IPv4地址,应该存储为4个字节。
如果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