美文网首页
Java/Kotlin 获取同子网所有 IP

Java/Kotlin 获取同子网所有 IP

作者: dengzii | 来源:发表于2020-12-04 16:20 被阅读0次

    Kotlin

    fun InetAddress.getHost(): List<InetAddress> {
    
        val bitMask = NetworkInterface.getByInetAddress(this)
                .interfaceAddresses[0].networkPrefixLength
        val netmask = (0xff_ff_ff_ff shl (32 - bitMask)).toInt()
        val ip = address[0].toLong() shl 24 or
                (address[1].toLong() shl 16 and (0xff shl 16)) or
                (address[2].toLong() shl 8 and (0xff shl 8)) or
                (address[3].toLong() and 0xff)
        val startIp = ip and netmask
        val hosts = mutableListOf<Long>()
        for (i in 1L until netmask.inv()) {
            val h = startIp or i
            if (h == ip){
                continue
            }
            hosts.add(startIp or i)
        }
        return hosts.map { InetAddress.getByName(ipToString(it)) }
    }
    private fun ipToString(address: Long): String {
        return (address ushr 24 and 0xFF).toString() + "." +
                (address ushr 16 and 0xFF) + "." +
                (address ushr 8 and 0xFF) + "." +
                (address and 0xFF)
    }
    fun main(){
        Inet4Address.getLocalHost().getHost().forEach {
            println(it.hostAddress)
        }
    }
    

    Java

        InetAddress localhost = Inet4Address.getLocalHost(); // 192.168.0.1/24
        NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localhost);
        
        int bitMask = networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength();   // 24
        int netmask = 0xff_ff_ff_ff << (32 - bitMask);  // 0xff_ff_ff_00
        byte[] ip4 = localhost.getAddress();    // [0xc0, 0xa8, 0x01, 0xa3]
        int ip = ip4[0] << 24 |
                ip4[1] << 16 & 0xff << 16 |
                ip4[2] << 8 & 0xff << 8 |
                ip4[3] & 0xff;  // 0xc0_a8_01_a3
        
        int startIp = ip & netmask; // 0xc0_a8_01_a3 & 0xff_ff_ff_00
        int endIp = ip | ~netmask; // 0xc0_a8_01_a3 | ~0xff_ff_ff_00
        
        List<Integer> host = new ArrayList<>();
        // skip first and last, self
        for (int i = 1, c = ~netmask; i < c; i++) {
            int h = startIp | i;
            if (h == ip) continue;
            host.add(startIp | i);
        }
        System.out.printf("%08x %s%n", ip, ipToString(ip));
        System.out.printf("%08x %s%n", startIp, ipToString(startIp));
        System.out.printf("%08x %s%n", endIp, ipToString(endIp));
        for (Integer integer : host) {
            System.out.println(ipToString(integer));
        }
    
        static String ipToString(int address) {
            return (address >>> 24 & 0xFF) + "." +
                    (address >>> 16 & 0xFF) + "." +
                    (address >>> 8 & 0xFF) + "." +
                    (address & 0xFF);
        }
    

    通过掩码位计算子网掩码

    掩: 掩盖, 表示你不必关注的东西. 码: 编码, 二进制. 位: 位置.

    掩码位为 0-32 整数, 越大表示可划分的主机数量越少. 掩码位如何隐射成掩码呢? 如下例子, 假设掩码位是 24, 其中 24 可以看做是 32 位中从做往右数有几个 1, 那么 24 就是有 24 个 1, 剩余的都是 0.

    11111111 11111111 11111111 00000000
    FF FF FF 00
    255 255 255 0
    

    我们把第一列二进制数依次往下转换成 16 进制, 10 进制, 得到了最终掩码就是 255.255.255.0.

    通过子网掩码计算子网 IP

    int start = ip & subnetMask;
    int end = ip | ~subnetMask;
    

    将当前 IP 按位 子网掩码 即可得到最小 IP, 将当前 IP 按位 子网掩码按位 即可得到最大 IP.

    子网掩码按位 既是子网 IP 数量.

    相关文章

      网友评论

          本文标题:Java/Kotlin 获取同子网所有 IP

          本文链接:https://www.haomeiwen.com/subject/fvfebktx.html