首页 > 解决方案 > Mysql:从二进制 ip 和子网获取 IPv6 二进制网络掩码

问题描述

我有一个将 IPv6 地址存储为 BINARY(16) 和子网存储为 INT(3) 的表

我认为通过以下方式获取网络掩码很简单:

SELECT ~INET6_ATON('::') << (128 - subnet);

但这返回零,事实上,当我在二进制字符串上使用它们时,所有按位运算符似乎都提供整数结果:-(

我正在使用 10.1.30-MariaDB

+-----------------+
| VERSION()       |
+-----------------+
| 10.1.30-MariaDB |
+-----------------+

非常感谢任何帮助。

编辑:我完全误解了 Maria 的版本字符串,抱歉 :-(

标签: mysqlmariadbipv6bitwise-operators

解决方案


5.5 中的位操作仅限于 64 位。(8.0放宽了限制。5.5已经很老了。如果升级,要么转储重新加载,要么分3步升级:5.5->5.6->5.7->8.0)

您可能想要右移>>或者也许(1 << amt) - 1。示例(仅使用 64 位算术):

SELECT HEX(~((1 << 8) - 1)); --> FFFFFFFFFFFFFF00

http://mysql.rjweb.org/doc.php/ipranges的“IPv6 参考实现”链接中提供了一些 128 位操作。没有“转变”功能,但您可以调整技术(使用HEX())来实现您的目的。它确实对 IPv6 值进行了加/减 1。这对于某些掩码构建和掩码操作很方便。

如果您想解释您将如何处理该结果SELECT,我也许可以给您更多的答案。

(在 5.7.11 发行说明中找到):

位函数和运算符包括BIT_COUNT()BIT_AND()BIT_OR()BIT_XOR()&| ^~<<>>。目前,位函数和运算符需要BIGINT(64 位整数)参数并返回BIGINT值,因此它们的最大范围为 64 位。其他类型的参数被转换为BIGINT并且可能会发生截断。

MySQL 8.0 的一个扩展改变了这种强制转换为BIGINT的行为:位函数和运算符允许二进制字符串类型参数(BINARYVARBINARYBLOB类型),使它们能够接受参数并产生大于 64 位的返回值。因此,在 MySQL 5.7 中对二进制字符串参数的位操作可能会在 MySQL 8.0 中产生不同的结果。为了提前通知这种潜在的行为变化,服务器现在为在 MySQL 8.0 中二进制字符串参数未转换为整数的位操作生成警告。这些警告提供了重写受影响语句的机会。要以升级到 8.0 后不会改变的方式显式生成 MySQL 5.7 行为,请将位操作二进制字符串参数转换为整数。有关更多信息和示例,请参阅位函数和运算符


推荐阅读