我有一个简单的表,其中包含如下 IP 范围(它们保存为 varchar,但如果需要,我可以更改它):
1.0.0.0/24
1.0.1.0/24
1.0.2.0/23
1.0.4.0/22
...etc
如何选择给定 IP 地址属于该范围的行?
类似于:
SELECT range FROM ipranges WHERE '195.124.199.201' IN range
编辑:建议的重复答案 MySQL check if an IP-address is in range?对我不起作用,因为它假设范围被指定为两个 IP 地址,但我的符号使用斜杠,我不知道如何在它们之间进行转换。
最佳答案
您需要使用INET_ATON()将 IPv4 地址格式转换为等效的无符号整数。
首先根据 CIDR notation 计算起始地址和结束地址.
mysql> SELECT INET_ATON(SUBSTRING_INDEX(range, '/', 1)) AS start_address,
POWER(2, 32-SUBSTRING_INDEX(range, '/', -1))-1 AS num_addresses
FROM ipranges;
+---------------+---------------+
| start_address | num_addresses |
+---------------+---------------+
| 16777216 | 255 |
+---------------+---------------+
该结果是我针对 '1.0.0.0/24'
测试此查询时得到的结果。
然后您可以检查您感兴趣的 IP 地址的 INET_ATON() 是否在该范围内,因为它只是一个整数范围。
SELECT range FROM (
SELECT range,
INET_ATON(SUBSTRING_INDEX(range, '/', 1)) AS start_address,
POWER(2, 32-SUBSTRING_INDEX(range, '/', -1))-1 AS num_addresses
FROM ipranges) AS t
WHERE INET_ATON('195.124.199.201') BETWEEN start_address AND start_address+num_addresses;
恐怕对于所有这些表达式,SQL 查询不可能通过索引进行优化。如果您需要它针对 IP 范围的大型数据集以高性能运行,您需要考虑一种以不同方式存储数据的方法,以便可以对其进行索引。
但是,如果您只有少量 IP 范围,即使是不可索引的查询也可能足够快。
关于mysql - 检查IP是否在MYSQL中的某个范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49390105/