这几天搞搞网站上面的随机图片API,做个访问控制,万一有人抓取网站图片,是吧,就挺那什么
以前用的是单IP屏蔽,然后发现,这个效率不高,人家重新拨号,又是一条汉子~
然后想起来了使用IP段屏蔽
遂疯狂百度,疯狂Google
发现了一种解决方案:
代码来自https://www.cnblogs.com/cqinwn/p/13854221.html
/// <summary> /// 验证IP地址是否被拒绝 /// </summary> /// <param name="ip"></param> /// <returns></returns> public bool ValidateIP(string ip) { long ipv = ip.Replace(".", "").ToLong(); string where = " (cast(replace(StartIP,'.','') as bigint)>=" + ipv + " and cast(replace(EndIP,'.','') as bigint)<=" + ipv + ") and FilterType=0 and EnabledMark=1"; int count = GetCountByWhere(where); return count > 0 ? true : false; }
这个代码是把IP地址的所有点去掉,形成一个Int64的数字,然后在数据库里进行比较
但是存在一个最严重的问题,那就是还会匹配(误伤)到其他的IP
举个例子
19216800(192.168.0.0)------------------1921681255(192.168.1.255)
19216800(192.168.0.0)<192168020(192.168.0.20)<1921681255(192.168.1.255)
这个没问题,是吧
19216800(192.168.0.0)<175167146(175.167.14.6)<1921681255(192.168.1.255)
发现了什么没有
175.167.14.6原本不属于这个IP段。假如我是175.167.14.6来访问,恰好这个网站是这个屏蔽规则,那么我就无法访问了,一个屏蔽内网IP的规则连带部分外网IP一起屏蔽掉了~
下面是我的解决方案
我是先把ip转为数字地址,再用数字地址去做比较,缺点就是需要在数据库存储数字地址(有解决办法的小伙伴欢迎留言哦)
public bool ValidateIP(string ip) { long ipv=convertIPtoInt(ip); string where = " (StartIP<=" + ipv + " and EndIP>=" + ipv + ") and FilterType=0 and EnabledMark=1"; int count = GetCountByWhere(where); return count > 0 ? true : false; } //将ipv4/v6地址转为数字地址 private long convertIPtoInt(string ip) { long IntIp = 0; string[] ips = ip.Split('.'); IntIp = long.Parse(ips[0]) << 0x18 | long.Parse(ips[1]) << 0x10 | long.Parse(ips[2]) << 0x8 | long.Parse(ips[3]); return IntIp; }
嗯,就酱紫o(* ̄▽ ̄*)o
微信扫码查看本文
发表评论