Mysql:从二进制IP和子网获取IPv6二进制网络掩码

时间:2018-11-04 10:27:24

标签: mysql mariadb ipv6 bitwise-operators

我有一张表,将IPv6地址存储为BINARY(16),将子网存储为INT(3)

我认为通过以下操作获得网络掩码会很简单:

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

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

我正在使用10.1.30-MariaDB

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

非常感谢任何帮助。

编辑:我完全误解了Maria的版本字符串,对不起:-(

1 个答案:

答案 0 :(得分:3)

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中,这些位操作的二进制字符串参数未转换为整数。这些警告为重写受影响的语句提供了机会。为了显式地产生MySQL 5.7行为,使其在升级到8.0后不会改变,请转换位操作二进制字符串参数以将其转换为整数。有关更多信息和示例,请参见Bit Functions and Operators