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ù)量.