【代码】C#结合数据库判断某IP地址是否属于某IP段

2021-02-24 15:23:22  阅读 1688 次 评论 0 条

这几天搞搞网站上面的随机图片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


微信扫码查看本文
本文地址:https://www.yangguangdream.com/?id=2126
版权声明:本文为原创文章,版权归 编辑君 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?