gpt4 book ai didi

php - 如何在 MySQL 中使用 INET_ATON 对 IP 地址进行通配符搜索?

转载 作者:行者123 更新时间:2023-11-29 04:05:41 25 4
gpt4 key购买 nike

我发现这种使用 INET_ATON 将 IP 地址作为整数存储在 MySQL 数据库中的方法:https://stackoverflow.com/a/5133610/4491952

由于 IPv4 地址是 4 字节长,您可以使用 INT (UNSIGNED)恰好有 4 个字节:

`ipv4` INT UNSIGNED

INET_ATONINET_NTOA转换它们:

INSERT INTO `table` (`ipv4`) VALUES (INET_ATON("127.0.0.1"));
SELECT INET_NTOA(`ipv4`) FROM `table`;

对于 IPv6 地址,您可以使用 BINARY相反:

`ipv6` BINARY(16)

并使用 PHP’s inet_ptoninet_ntop用于转换:

'INSERT INTO `table` (`ipv6`) VALUES ("'.mysqli_real_escape_string(inet_pton('2001:4860:a005::68')).'")'
'SELECT `ipv6` FROM `table`'
$ipv6 = inet_pton($row['ipv6']);

但是如何使用 INET_ATON 和 PHP 的 ip2long 函数进行通配符搜索,例如 192.168.%?

最佳答案

MySQL 提供的一个绝妙技巧是位移位。您可以使用它来查看 ip 是否包含在以 cidr 表示法编写的地址 block 中。您可以使用此方法将您的地址视为 X.X.X.X/16 cidr block 。

set @cidr_block:='10.20.30.40/16';

select inet_ntoa(inet_aton(substring_index(@cidr_block,'/',1))>>(32-substring_index(@cidr_block,'/',-1))<<(32-substring_index(@cidr_block,'/',-1))) as first_ip,
inet_aton(substring_index(@cidr_block,'/',1))>>(32-substring_index(@cidr_block,'/',-1))<<(32-substring_index(@cidr_block,'/',-1)) as first_ip_num,
inet_ntoa((((inet_aton(substring_index(@cidr_block,'/',1))>>(32-substring_index(@cidr_block,'/',-1)))+1)<<(32-substring_index(@cidr_block,'/',-1)))-1) as last_ip,
(((inet_aton(substring_index(@cidr_block,'/',1))>>(32-substring_index(@cidr_block,'/',-1)))+1)<<(32-substring_index(@cidr_block,'/',-1)))-1 as last_ip_num
;
+-----------+--------------+---------------+-------------+
| first_ip | first_ip_num | last_ip | last_ip_num |
+-----------+--------------+---------------+-------------+
| 10.20.0.0 | 169082880 | 10.20.255.255 | 169148415 |
+-----------+--------------+---------------+-------------+
1 row in set (0.00 sec)

查看 ip 是否在地址 block 中的快捷方式 - 只需筛选 cidr 地址和 ip 以查看它们是否相同。当然,如果应用于存储值,这将是表扫描。

select inet_aton('127.0.0.1')>>16 = inet_aton('127.0.10.20')>>16 as `1 = true`;
+----------+
| 1 = true |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)

select inet_aton('127.0.0.1')>>16 = inet_aton('127.10.10.20')>>16 as `0 = false`;
+-----------+
| 0 = false |
+-----------+
| 0 |
+-----------+
1 row in set (0.00 sec)

关于php - 如何在 MySQL 中使用 INET_ATON 对 IP 地址进行通配符搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42908785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com