• 浅谈IP黑名单高效设置与查询


    IP黑名单设置与查询

    • 按照最普通的思路,我们设置一个boolean类型的数组,将IP地址映射到本地内存中,也就是为每一个IP地址分配一个boolean数组的一个下标,用来表示该IP在不在黑名单中。由于IPv4中共有2^ 32个IP地址,因此共需要4GB内存用来存放boolean类型的数组。我们可以想到,用一个二进制位来表示一个IP地址在不在黑名单中,我们只需要用一个512MB的数组即可为IPv4中的所有IP地址分配一个二进制位。通过 IP / 8来获取IP的状态映射到的字节,通过IP % 8来获取IP的状态映射在在这个字节的哪一位。
    public class IpBlack {
    
        private static byte[] ip = new byte[1 << 29]; // IP地址映射到本地内存数据的数组,用每个字节中的每一个位表示一个IP地址是不是在黑名单中,也就是说2的32次方个IP地址可以映射到2的32次方个位上,也就是2的29次方个字节上
        private Byte mask = new Byte("11111111"); // 用来做异或运算
    
        // 通过IP >> 3 (IP / 8) 来计算该IP地址对应的字节,通过IP & 7 (IP % 8)来计算该IP地址在对应某个字节中的位置
        boolean isBlack(long input) {
            // 查询本地内存数组中,第IP / 8 个字节中第IP % 8个位是否为1,这代表了这个IP地址是否在黑名单中
            return (ip[(int)(input >> 3)] & (1 << (input & 7))) == 1 ? true : false;
        }
    
        void setBlack(long input, boolean isBlack) {
            int byteIndex = (int)(input >> 3);
            byte idx = (byte)(1 << (input & 7));
            if(isBlack) {
                // 将数组中对应字节对应位的二进制变为1
                ip[byteIndex] = (byte)(ip[byteIndex] | idx);
            } else {
                // 将数组中对应字节对应位的二进制变为0
                ip[byteIndex] = (byte)(ip[byteIndex] & (idx ^ mask));
            }
        }
    
    }
    
    时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面…… 没有谁生来就是神牛,而千里之行,始于足下!
  • 相关阅读:
    Outlook同步问题
    Excel下三角图解的绘制
    数据库,SQL,万恶之源?
    新年第一篇
    ArcGIS的GeoProcessing的原理及实现(1)
    如何在多个文件中查找需要的信息
    关于GIS门户(GIS Portal)的概念
    2004总结
    MapViewControl更新
    GCDPlot 0.22 介绍
  • 原文地址:https://www.cnblogs.com/bianjunting/p/14664708.html
Copyright © 2020-2023  润新知