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();
    }

測試了幾遍,沒啥問題,如果有更好的思路和實現方法,麻煩提供一下,謝謝啦,

        就先這樣了,寫的很急,也沒來的及優化,捕獲異常,變量名標準之類的,各位看官如果需要,記得捕獲異常優化一下然後多測幾遍,我得下班了。     

 

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