我有一张表,将IPv6地址存储为BINARY(16),将子网存储为INT(3)
我认为通过以下操作获得网络掩码会很简单:
SELECT ~INET6_ATON('::') << (128 - subnet);
但这返回零,实际上,当我在二进制字符串上使用它们时,所有按位运算符似乎都可以提供整数结果:-(
我正在使用10.1.30-MariaDB
+-----------------+
| VERSION() |
+-----------------+
| 10.1.30-MariaDB |
+-----------------+
非常感谢任何帮助。
编辑:我完全误解了Maria的版本字符串,对不起:-(
答案 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的行为:位函数和运算符允许使用二进制字符串类型的参数(BINARY,VARBINARY和BLOB类型),使他们能够接受参数并产生大于64位的返回值。因此,在MySQL 5.7中对二进制字符串参数进行位操作可能会在MySQL 8.0中产生不同的结果。为了提前通知这种潜在的行为变化,服务器现在会针对位操作生成警告,在MySQL 8.0中,这些位操作的二进制字符串参数未转换为整数。这些警告为重写受影响的语句提供了机会。为了显式地产生MySQL 5.7行为,使其在升级到8.0后不会改变,请转换位操作二进制字符串参数以将其转换为整数。有关更多信息和示例,请参见Bit Functions and Operators。