java mysql ipv6_在CIDR范围MySQL中找到IPv6的正确方法

我有一个MySQL黑名单表,其中存储了两种类型之一的单个IPv4,IPv6或CIDR范围 .

我的表看起来有点像这样:

+-----------+-------------+

| Name | Type |

+-----------+-------------+

| IpAddress | VARCHAR(46) |

+-----------+-------------+

| Mask | INT(2) |

+-----------+-------------+

现在,我想检查一个给定的IP地址是否在一个已保存的CIDR范围内 . 在研究了很多页面后,我已经完成了这个,最后只是将以下解决方案移植到了MySQL:PHP5 calculate IPv6 range from cidr prefix?

因此,我将IP CIDR掩码转换为该范围内的第一个和最后一个IP,然后使用INET6_ATON将其转换为数字,并将其与BETWEEN运算符进行比较 .

我的实施:

Get last ip

FUNCTION (`Ip` VARCHAR(46), `Mask` INT(2) UNSIGNED) RETURNS varchar(39)

BEGIN

DECLARE IpNumber VARBINARY(16);

DECLARE Last VARCHAR(39) DEFAULT '';

DECLARE FlexBits, Counter, Deci, NewByte INT UNSIGNED;

DECLARE HexIp VARCHAR(32);

SET IpNumber = INET6_ATON(Ip);

SET HexIp = HEX(IpNumber);

SET FlexBits = 128 - Mask;

SET Counter = 32;

WHILE (FlexBits > 0) DO

SET Deci = CONV(SUBSTR(HexIp, Counter, 1), 16, 10);

SET NewByte = Deci | (POW(2, LEAST(4, FlexBits)) - 1);

SET Last = CONCAT(CONV(NewByte, 10, 16), Last);

IF FlexBits >= 4 THEN SET FlexBits = FlexBits - 4;

ELSE SET FlexBits = 0;

END IF;

SET Counter = Counter - 1;

END WHILE;

SET Last = CONCAT(SUBSTR(HexIp, 1, Counter), Last);

RETURN INET6_NTOA(UNHEX(Last));

END

Get first ip

FUNCTION (`Ip` VARCHAR(46), `Mask` INT(2) UNSIGNED, `WithMask` BOOLEAN) RETURNS varchar(39)

BEGIN

DECLARE First VARCHAR (42) DEFAULT '';

SET First = INET6_NTOA(UNHEX(RPAD(SUBSTR(HEX(INET6_ATON(Ip)), 1, Mask / 4), 32, 0)));

IF (WithMask = 1) THEN

SET First = CONCAT(First, '/', CAST(Mask AS CHAR));

END IF;

RETURN First;

END

这很好用!我只是想到使用一些聪明的位操作可以更有效地完成它 . 我已经阅读了很多关于这个主题的问题,但我并没有真正找到具体的解决方案任何正确方向的帮助都会非常感激!

NOTE :只有IPv6,我才能以正确的方式实现IPv4 .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值