mysql - 检查IP是否在MYSQL中的某个范围内

标签 mysql ip-address cidr

我有一个简单的表,其中包含如下 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/

相关文章:

mysql - 无法在 Windows 10 上的 MySQL 8.x 中设置 lower_case_table_names

django - 如何在本地测试使用 example.com 域访问它的 Django 项目?

algorithm - 如何有效地存储 IP 地址和 CIDR 范围

regex - CIDR 表示法中 IPV6 地址的正则表达式

php - 将mysql数据放入html中存在的div中

mysql - 如何仅将较新的帖子从一个 Mediawiki MySQL 迁移到另一个?

c# - 将列添加到另一个表并作为列表返回 C#

ip - 多个 IP + KVM 桥接器

mysql - 有没有办法直接从 SELECT 查询中将 IP 与 IP+CIDR​​ 匹配?

从 IP 范围到 CIDR 掩码的转换