Java/Kotlin 獲取同子網(wǎng)所有 IP

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

通過掩碼位計算子網(wǎng)掩碼

掩: 掩蓋, 表示你不必關(guān)注的東西. 碼: 編碼, 二進(jìn)制. 位: 位置.

掩碼位為 0-32 整數(shù), 越大表示可劃分的主機(jī)數(shù)量越少. 掩碼位如何隱射成掩碼呢? 如下例子, 假設(shè)掩碼位是 24, 其中 24 可以看做是 32 位中從做往右數(shù)有幾個 1, 那么 24 就是有 24 個 1, 剩余的都是 0.

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

我們把第一列二進(jìn)制數(shù)依次往下轉(zhuǎn)換成 16 進(jìn)制, 10 進(jìn)制, 得到了最終掩碼就是 255.255.255.0.

通過子網(wǎng)掩碼計算子網(wǎng) IP

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

將當(dāng)前 IP 按位 子網(wǎng)掩碼 即可得到最小 IP, 將當(dāng)前 IP 按位 子網(wǎng)掩碼按位 即可得到最大 IP.

子網(wǎng)掩碼按位 既是子網(wǎng) IP 數(shù)量.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。