如何在mysql中将二进制转换为整数?

Posted

技术标签:

【中文标题】如何在mysql中将二进制转换为整数?【英文标题】:How to convert binary to integer in mysql? 【发布时间】:2013-07-02 02:25:30 【问题描述】:

把我的问题放在正确的角度:

我有一个 php 应用程序,它将用户的 IP 存储在 mysql 表中。

列类型为VARBINARY(16),应用使用PHP的inet_pton形成二进制字符串。

这是一个典型 IP4 地址的字符串有 4 个字节。

如何从表格中检索这些 IP,并以人类可读的形式显示它们?

我目前的解决方案是:

select INET_NTOA(CONV(HEX(ip),16,10)) from operation_ip;

有没有更直接的方法?

尤其是CONV(HEX(x),16,10)将4个字节变成整数的最简单方法(实际上我认为它甚至不是整数,而是看起来像整数的字符串)。

(我使用 VARBINARY(16),因为 PHP 的 inet_pton 可以返回 16 字节的 IPv6 地址。AFAIK MySQL 的 INET_NTOA 不支持 IPv6,但目前这不是我最关心的问题)。

【问题讨论】:

如果你想要一个更直接的形式,不要将IP地址转换为二进制以便将其存储在数据库中......或者同时使用地址的字符串和数据库中的二进制值. 【参考方案1】:

MySQL 有很好的内置函数来处理这种情况:

INSERT INTO t(ip) VALUE (INET_ATON('1.2.3.4')); -- stores integer 16909060
SELECT INET_NTOA(ip) FROM t; -- returns string '1.2.3.4'

或者PHP方式:

$sql = 'INSERT INTO t(ip) VALUE (' . ip2long('1.2.3.4') . '))'; 
// ip2long('1.2.3.4') = 16909060
// reverse conversion: long2ip(16909060) returns '1.2.3.4'

【讨论】:

如果我理解正确,您的解决方案是使用 4 字节整数作为列的类型。不幸的是 IPv6 需要 16 字节,而 MySQL 不支持这么长的整数,这就是我使用 VARBINARY(16) 的原因。另一方面,在某些查询中,我 100% 确定结果只包含具有 IPv4 地址的行,在这种情况下,我想快速将 VARBINARY(16) 转换为(4 字节)INT。 我忽略了 IPv6 的问题,因为您写道“IPv6 (...) 不是我最关心的问题”。从 v5.6.3 开始,MySQL 的功能正是您所需要的:INET6_ATON()INET6_NTOA()。在那之前,你的方法可能是最好的方法。不过,我不会将 IPv4 和 IPv6 存储在同一列中,而是存储在不同的列中。

以上是关于如何在mysql中将二进制转换为整数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ruby 中将字符串或整数转换为二进制?

如何在 Ruby 中将字符串或整数转换为二进制?

如何在 elixir 中将二进制转换为 base10(十进制)整数

如何在JavaScript中将数字的二进制表示从字符串转换为整数?

如何在 Java 中将二进制字符串转换为以 10 为底的整数

如何在Javascript中将整数转换为具有固定长度的十六进制?