java 实现查询IP地址是否在某网段中的小工具

       今天拿到个需求要搜索ip地址匹配时候需要匹配网段中的IP,靠network网段地址后面的掩码长度计算是否包含某个ip,这种事情,我们每次都是网上找个在线计算器算一下,   不过想了想这么多策略包含太多的网段,有的是这种场景需要查询某个ip是否在某个网段中,所以理了理思路写个方法

 1、网段地址,可以根据掩码长度来计算出来主机范围,

       我们的掩码格式:ip/mask-length 即:172.30.28.0/24,很标准的使用网段网关地址/子网掩码来表示,

2、计算给定IP的二进制地址,判断主机位是否在这个网段中

写个方法试试看:

 /**
     * 判断给定IP地址是否在指定网段中
     * network  eg:172.30.29.0/25
     * ip       eg: 172.30.29.129
     * @param network
     * @param ip
     * @return
     */

    public Boolean isContains(String network, String ip) {
        String[] networkArr = network.split("/");
        String networkBin = transIpToBrinary(networkArr[0]);
        String ipBin = transIpToBrinary(ip);

        int mask = Integer.parseInt(networkArr[1]);
        //如果掩码长度不在1-32之间,就直接比较俩地址吧
        if (mask < 0 || mask >= 32)
            return ip.equals(network);

        //这一步实际是想求ip地址的大段,没想好怎么算,就先这样算了
        int targetMask = mask / 8;
        int newMask = targetMask * 8;
        //根据network地址求出网段中最大的主机地址
        // (这里包含广播地址,既然是匹配IP是否在此网段中,就未对广播地址及网关地址清除)
        StringBuilder networkMaxHostBuilder = new StringBuilder();
        networkMaxHostBuilder.append(networkBin, 0, mask);  //取网络位
        for (int i = mask; i < 32; i++) {
            networkMaxHostBuilder.append("1");  // 主机位补上1,这就拼成了此网段中最大主机地址
        }

        //截取主机位转换为十进制,进行比较
        int networkMinHost = Integer.parseInt(networkBin.substring(newMask, 32), 2);
        int networkMaxHost = Integer.parseInt(networkMaxHostBuilder.substring(newMask, 32), 2);
        int ipBinary = Integer.parseInt(ipBin.substring(newMask, 32), 2);
        //网络位要相等
        if (networkBin.substring(0, newMask).equals(ipBin.substring(0, newMask))) {
            //且必须在主机地址中
            if (ipBinary >= networkMinHost && ipBinary <= networkMaxHost)
                return true;
        }
        return false;
    }


    /**
     * 转换ip地址
     * @param ip
     * @return
     */
    private String transIpToBrinary(String ip) {
        String[] ipArr = ip.split("\\.");
        String net;
        StringBuilder netBuilder = new StringBuilder();
        int ipLen = ipArr.length;
        for (int i = 0; i < ipLen; i++) {
            net = doTransToBinary(ipArr[i]);
            netBuilder.append(net);
        }
        return netBuilder.toString();
    }

    /**
     * 转换十进制为二进制
     * @param ip
     * @return
     */
    private String doTransToBinary(String ip) {
        int numInt = Integer.parseInt(ip);
        StringBuilder binaryBuilder = new StringBuilder();
        for (int i = 7; i >= 0; i--) {
            int binary = numInt >>> i & 1;
            binaryBuilder.append(binary);
        }
        return binaryBuilder.toString();
    }

测试了几遍,没啥问题,如果有更好的思路和实现方法,麻烦提供一下,谢谢啦,

        就先这样了,写的很急,也没来的及优化,捕获异常,变量名标准之类的,各位看官如果需要,记得捕获异常优化一下然后多测几遍,我得下班了。     

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章