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

Java 將 IPv4 地址轉換為長整型 (long) 的高效實現與邊界處理

     編輯:Java 相關知識

IPv4 地址 (如 192.168.1.1) 本質是 32 位無符號整數。Java 無無符號類型,通常用 long 存儲 (範圍 0 ~ 4,294,967,295)。本文提供健壯的工具方法,含輸入校驗、位運算轉換、異常防護。

一、核心算法:位移拼接

public static long ipToLong(String ip) {
    if (ip == null || ip.isEmpty()) return 0L;
    
    // 1. 清洗輸入:只保留數字和點
    String cleaned = ip.replaceAll("[^0-9.]", "").trim();
    
    // 2. 分割四段
    String[] parts = cleaned.split("\\.");
    if (parts.length != 4) {
        throw new IllegalArgumentException("Invalid IPv4 format: " + ip);
    }
    
    // 3. 解析並位移拼接 (無符號右移 >>> 0 確保正數)
    long result = 0L;
    for (int i = 0; i < 4; i++) {
        int octet = Integer.parseInt(parts[i]);
        if (octet < 0 || octet > 255) {
            throw new IllegalArgumentException("Octet out of range 0-255: " + octet);
        }
        result = (result << 8) | (octet & 0xFFL);
    }
    return result;
}

二、原理圖解

IP:  192   .   168   .   1   .   1
      ↓       ↓       ↓       ↓
    11000000 10101000 00000001 00000001  (二進制)
      ↓       ↓       ↓       ↓
   << 24    << 16    << 8    << 0
      ↓       ↓       ↓       ↓
   3232235777  (十進制 long = 0xC0A80101)

三、完整工具類 (含反向轉換、校驗、單元測試點)

public final class IpUtil {
    private IpUtil() {}

    /** IPv4 字符串 → long (無符號 32 位) */
    public static long ipToLong(String ip) {
        if (ip == null) return 0L;
        String cleaned = ip.replaceAll("[^0-9.]", "").trim();
        String[] parts = cleaned.split("\\.");
        if (parts.length != 4) throw new IllegalArgumentException("Invalid IPv4: " + ip);
        
        long result = 0L;
        for (String part : parts) {
            int octet = Integer.parseInt(part);
            if (octet < 0 || octet > 255) throw new IllegalArgumentException("Octet 0-255: " + octet);
            result = (result << 8) | (octet & 0xFFL);
        }
        return result;
    }

    /** long → IPv4 字符串 */
    public static String longToIp(long ipLong) {
        // 無符號右移 >>> 確保高位補 0
        return ((ipLong >>> 24) & 0xFF) + "." +
               ((ipLong >>> 16) & 0xFF) + "." +
               ((ipLong >>> 8)  & 0xFF) + "." +
               (ipLong & 0xFF);
    }

    /** 校驗合法 IPv4 */
    public static boolean isValidIpv4(String ip) {
        if (ip == null) return false;
        String regex = "^((25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d?\\d)$";
        return ip.matches(regex);
    }
    
    // 單元測試示例
    public static void main(String[] args) {
        String ip = "192.168.1.1";
        long l = ipToLong(ip);           // 3232235777
        String back = longToIp(l);       // "192.168.1.1"
        System.out.println(ip + " -> " + l + " -> " + back);
        assert ip.equals(back);
        
        // 邊界測試
        System.out.println("0.0.0.0 -> " + ipToLong("0.0.0.0"));           // 0
        System.out.println("255.255.255.255 -> " + ipToLong("255.255.255.255")); // 4294967295
    }
}

四、常見坑點與最佳實踐

坑點後果修正
用 int 接收高位符號位導致負數,比較/存儲錯誤統一用 long,數據庫用 BIGINT UNSIGNED 或 DECIMAL(10,0)
直接 Long.parseLong 不校驗非法輸入拋 NumberFormatException 或產生錯誤值正則校驗 + 分段解析 + 範圍檢查
忽略 BOM/隱形字符 (如 \uFEFF)解析失敗 For input string: \"\uFEFF0\"調用前 ip = ip.replaceAll("\\p{C}", "").trim() 移除控制字符
符號右移 >> 而非無符號 >>>>高位補 1 導致反解錯誤反解時**全部用 >>>>**

五、應用場景

  • 數據庫存儲 IP (索引效率高於字符串,支持範圍查詢 BETWEEN)。
  • IP 歸屬地庫 (起始 IP - 結束 IP 映射地區),二分查找極快。
  • 網絡設備配置、ACL 規則、防火牆策略的內存計算。
  • 分布式系統節點標識、一致性哈希環映射。

六、總結

IPv4 String ⇄ Long 轉換核心是 **8 位分段位移拼接/拆解**,關鍵在 **輸入清洗校驗**、**無符號右移 >>>>**、**長整型存儲**。封裝為工具類並覆蓋邊界測試,即可安全用於生產環境。

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