首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java IP 地址工具類全解析:長整數轉換、掩碼計算、CIDR 範圍一網打盡

     編輯:Java 相關知識

功能清單

  • IPv4 字符串 ⇄ Long 數值 雙向轉換
  • 掩碼位數 ⇄ 子網掩碼 互換
  • 給定 IP + 掩碼位,計算網段起始/結束 IP
  • 子網掩碼 → 掩碼位數
  • 子網可用主機數計算

核心代碼精講

1. IP 字符串與 Long 互轉

/** Long → x.x.x.x */
public static String longToIp(long ip) {
    return ((ip >>> 24) & 0xFF) + "." +
           ((ip >>> 16) & 0xFF) + "." +
           ((ip >>> 8)  & 0xFF) + "." +
           (ip & 0xFF);
}

/** x.x.x.x → Long */
public static long ipToLong(String ip) {
    long result = 0;
    for (String seg : ip.split("\\.")) {
        result = (result << 8) + Long.parseLong(seg);
    }
    return result;
}

使用無符號右移 >>>> 與位運算,效能遠超字符串拼接。

2. 掩碼位數與點分十進制掩碼互轉

private static final Map MASK_CACHE = new HashMap<>();
static {
    for (int i = 1; i <= 32; i++) {
        long mask = i == 32 ? 0xFFFFFFFFL : (0xFFFFFFFFL << (32 - i));
        MASK_CACHE.put(i, longToIp(mask));
    }
}

public static String bitToMask(int bits) {
    return MASK_CACHE.getOrDefault(bits, "0.0.0.0");
}

public static int maskToBit(String mask) {
    return ipToLong(mask) == 0 ? 0 : Long.bitCount(ipToLong(mask));
}

靜態緩存 32 條映射,O(1) 查詢;Long.bitCount 一行搞定反向解析。

3. CIDR 網段範圍計算

/** 返回網段起始 IP (Long) */
public static long networkStart(String ip, int maskBits) {
    return ipToLong(ip) & ipToLong(bitToMask(maskBits));
}

/** 返回網段結束 IP (Long) */
public static long networkEnd(String ip, int maskBits) {
    long start = networkStart(ip, maskBits);
    long hostBits = ~ipToLong(bitToMask(maskBits)) & 0xFFFFFFFFL;
    return start | hostBits;
}

/** 可用主機數 = 2^(32-mask) - 2 */
public static long usableHosts(int maskBits) {
    if (maskBits <= 0 || maskBits >= 32) return 0;
    return (1L << (32 - maskBits)) - 2;
}

單元測試驗證

@Test
public void testCidr() {
    String ip = "218.240.38.69";
    int mask = 30;  // 255.255.255.252

    assertEquals("218.240.38.68", longToIp(networkStart(ip, mask)));
    assertEquals("218.240.38.71", longToIp(networkEnd(ip, mask)));
    assertEquals(2, usableHosts(mask));  // 僅 .69 .70 可用
}

工程化建議

  1. 改用 java.net.InetAddress 或第三方庫 避免手寫解析 Bug
  2. IPv6 需用 Inet6Address + 128 位 BigInteger
  3. 生產環境推薦 com.google.guava:guava 的 InetAddresses 或 ipaddress 庫

完整類結構

public final class IpUtils {
    private IpUtils() {}  // 工具類禁止實例化

    // 上述所有 static 方法
    // ...
}

一個精心設計的 IpUtils,能讓網絡相關業務代碼乾淨如新。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved