| 類別 | 首位元組範圍 | 二進位開頭 | 網路數 | 主機數/網路 | 用途 |
|---|---|---|---|---|---|
| A | 1 - 126 | 0xxxxxxx | 126 | 16,777,214 | 大型網路 |
| B | 128 - 191 | 10xxxxxx | 16,384 | 65,534 | 中型網路 |
| C | 192 - 223 | 110xxxxx | 2,097,152 | 254 | 小型網路 |
| D | 224 - 239 | 1110xxxx | N/A | N/A | 多播 |
| E | 240 - 255 | 1111xxxx | N/A | N/A | 保留/實驗 |
特殊保留:127.x.x.x (回環)、0.0.0.0 (本網路)、255.255.255.255 (廣播)、169.254.x.x (APIPA)、私有網段 (10.x、172.16-31.x、192.168.x)
import java.net.*;
public class IpAnalyzer {
public static void main(String[] args) throws Exception {
// 1. 獲取本機所有 IP
System.out.println("=== 本機 IP ===");
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
// 過濾回環、關閉、虛擬介面
if (ni.isLoopback() || !ni.isUp() || ni.isVirtual()) continue;
Enumeration addresses = ni.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress ia = addresses.nextElement();
if (ia instanceof Inet4Address) { // 只看 IPv4
System.out.printf("介面: %-10s IP: %-15s 類別: %s%n",
ni.getName(), ia.getHostAddress(), getIpClass(ia));
}
}
}
// 2. 域名解析
System.out.println("\n=== 域名解析 ===");
InetAddress[] google = InetAddress.getAllByName("www.google.com");
for (InetAddress ia : google) {
System.out.println(ia.getHostAddress() + " -> " + getIpClass(ia));
}
// 3. byte[] 處理陷阱
InetAddress local = InetAddress.getByName("192.168.1.100");
byte[] bytes = local.getAddress(); // 有號 byte (-128~127)
System.out.println("\n=== byte[] 處理 ===");
for (byte b : bytes) {
// 錯誤:直接印 b 會出現負數
// 正確:轉無號 int
int unsigned = b & 0xFF;
System.out.print(unsigned + " ");
}
}
/**
* 判斷 IPv4 地址類別 (基於首位元組)
*/
public static String getIpClass(InetAddress ia) {
if (!(ia instanceof Inet4Address)) return "IPv6";
byte[] bytes = ia.getAddress();
int firstOctet = bytes[0] & 0xFF; // 關鍵:無號轉換
if (firstOctet == 127) return "Loopback (A類保留)";
if (firstOctet == 0) return "Current Network";
if (firstOctet >= 240) return "E 類 (保留)";
if (firstOctet >= 224) return "D 類 (多播)";
if (firstOctet >= 192) return "C 類";
if (firstOctet >= 128) return "B 類";
if (firstOctet >= 1) return "A 類";
return "Unknown";
}
}
// Java byte 為有號 (-128 ~ 127)
// IP 位元組為無號 (0 ~ 255)
// 必須用 & 0xFF 或 Byte.toUnsignedInt() 轉換
byte b = (byte) 200; // 實際位元模式 11001000
int signed = b; // -56 (錯誤解讀)
int unsigned = b & 0xFF; // 200 (正確)
int unsigned2 = Byte.toUnsignedInt(b); // Java 8+ 200 (正確)
// 完整 IP 轉長整數 (用於比較/存儲)
public static long ipToLong(InetAddress ia) {
byte[] bytes = ia.getAddress();
long result = 0;
for (byte b : bytes) {
result = (result << 8) | (b & 0xFF);
}
return result;
}
// 長整數轉 IP 字串
public static String longToIp(long ip) {
return ((ip >> 24) & 0xFF) + "." +
((ip >> 16) & 0xFF) + "." +
((ip >> 8) & 0xFF) + "." +
(ip & 0xFF);
}
import java.net.*;
import java.util.*;
public class IpUtils {
// 私有網段 CIDR
private static final List PRIVATE_RANGES = Arrays.asList(
new Inet4AddressRange("10.0.0.0", "10.255.255.255"), // 10/8
new Inet4AddressRange("172.16.0.0", "172.31.255.255"), // 172.16/12
new Inet4AddressRange("192.168.0.0", "192.168.255.255") // 192.168/16
);
// 其他保留段
private static final List RESERVED_RANGES = Arrays.asList(
new Inet4AddressRange("127.0.0.0", "127.255.255.255"), // 回環
new Inet4AddressRange("169.254.0.0", "169.254.255.255"), // APIPA
new Inet4AddressRange("224.0.0.0", "239.255.255.255"), // 多播 D類
new Inet4AddressRange("240.0.0.0", "255.255.255.255") // 保留 E類
);
public static boolean isPrivate(InetAddress ia) {
if (!(ia instanceof Inet4Address)) return false;
long ip = ipToLong(ia);
return PRIVATE_RANGES.stream().anyMatch(r -> r.contains(ip));
}
public static boolean isLoopback(InetAddress ia) {
return ia.isLoopbackAddress() || isInRange(ia, "127.0.0.0", "127.255.255.255");
}
public static boolean isPublic(InetAddress ia) {
return !(isPrivate(ia) || isLoopback(ia) || ia.isMulticastAddress() || ia.isAnyLocalAddress());
}
public static String getIpType(InetAddress ia) {
if (ia.isLoopbackAddress()) return "Loopback";
if (ia.isMulticastAddress()) return "Multicast (D類)";
if (ia.isAnyLocalAddress()) return "Unspecified (0.0.0.0)";
if (isPrivate(ia)) return "Private (RFC1918)";
if (ia instanceof Inet4Address) return "Public IPv4 (" + getIpClass(ia) + ")";
return "IPv6";
}
// 內部範圍檢查輔助類
static class Inet4AddressRange {
final long start, end;
Inet4AddressRange(String startIp, String endIp) {
this.start = ipToLong(parseIp(startIp));
this.end = ipToLong(parseIp(endIp));
}
boolean contains(long ip) { return ip >= start && ip <= end; }
}
static InetAddress parseIp(String ip) {
try { return InetAddress.getByName(ip); }
catch (UnknownHostException e) { throw new IllegalArgumentException(e); }
}
}
java.net.NetworkInterface:枚舉網卡、獲取介面屬性 (MTU、MAC、MTU)com.google.common.net.InetAddresses (Guava):isInetAddress(), forString(), toAddrString()org.apache.commons.net.util.SubnetUtils:CIDR 範圍判斷 new SubnetUtils("192.168.1.0/24").getInfo().isInRange(ip)Inet6Address、NetworkInterface.getInetAddresses() 同時返回 v4/v6