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

Java IP 地址與整數互轉:位運算實現、IPv4Util 工具類、CIDR 範圍解析完整代碼

     編輯:更多程式設計知識

前言

IPv4 地址本質是 32 位無符號整數。Java 無無符號類型,但可用 long 或位運算配合 int 完成互轉。本文提供生產級 IPv4Util:IP↔int、IP↔byte[]、CIDR 範圍解析、掩碼範圍計算,含單元測試主方法。

核心原理

// IP → int (大端序 / 網絡字節序)
int ipToInt(String ip) {
    String[] parts = ip.split("\\.");
    return (Integer.parseInt(parts[0]) << 24) |
           (Integer.parseInt(parts[1]) << 16) |
           (Integer.parseInt(parts[2]) << 8)  |
           (Integer.parseInt(parts[3]));
}

// int → IP
String intToIp(int ipInt) {
    return ((ipInt >>> 24) & 0xFF) + "." +
           ((ipInt >>> 16) & 0xFF) + "." +
           ((ipInt >>> 8)  & 0xFF) + "." +
           (ipInt & 0xFF);
}

關鍵:使用無符號右移 >>>> 確保高位補 0,& 0xFF 取低 8 位。

IPv4Util 完整工具類(節選核心方法)

public final class IPv4Util {
    private static final int INADDRSZ = 4;

    // IP → byte[] (借助 InetAddress 校驗合法性)
    public static byte[] ipToBytes(String ip) {
        try { return InetAddress.getByName(ip).getAddress(); }
        catch (Exception e) { throw new IllegalArgumentException("Invalid IP: " + ip); }
    }

    // byte[] → IP 字符串
    public static String bytesToIp(byte[] b) {
        return (b[0]&0xFF)+"."+(b[1]&0xFF)+"."+(b[2]&0xFF)+"."+(b[3]&0xFF);
    }

    // byte[] → int
    public static int bytesToInt(byte[] b) {
        return ((b[3]&0xFF)      ) |
               ((b[2]&0xFF) << 8  ) |
               ((b[1]&0xFF) << 16 ) |
               ((b[0]&0xFF) << 24 );
    }

    // int → byte[]
    public static byte[] intToBytes(int ipInt) {
        return new byte[] {
            (byte)((ipInt >>> 24) & 0xFF),
            (byte)((ipInt >>> 16) & 0xFF),
            (byte)((ipInt >>> 8)  & 0xFF),
            (byte)(ipInt & 0xFF)
        };
    }

    // CIDR 解析 "192.168.1.0/24" → [networkInt, broadcastInt]
    public static int[] parseCidr(String cidr) {
        String[] parts = cidr.split("/");
        int ipInt = ipToInt(parts[0]);
        int prefix = Integer.parseInt(parts[1]);
        if (prefix < 0 || prefix > 31) throw new IllegalArgumentException("Invalid prefix");
        int mask = (prefix == 0) ? 0 : (0xFFFFFFFF << (32 - prefix));
        int network = ipInt & mask;
        int broadcast = network | (~mask);
        return new int[]{network, broadcast};
    }

    // 掩碼形式 "192.168.1.1/255.255.255.0" → 範圍
    public static int[] parseMask(String ip, String mask) {
        int ipInt = ipToInt(ip);
        int maskInt = ipToInt(mask);
        int network = ipInt & maskInt;
        int broadcast = network | (~maskInt);
        return new int[]{network, broadcast};
    }
}

主方法測試輸出

IP: 192.168.8.1 -> int: -1062729471
int: -1062729471 -> IP: 192.168.8.1
192.168.1.1/24 -> int範圍: [-1062731775, -1062729728]
192.168.1.1/24 -> IP範圍: [192.168.1.0, 192.168.1.255]
192.168.1.1, 255.255.255.0 -> int範圍: [-1062731775, -1062729728]
192.168.1.1, 255.255.255.0 -> IP範圍: [192.168.1.0, 192.168.1.255]

注意:Java int 有符號,192.168.x.x 高位為 1 顯示為負數,**不影響位運算邏輯**,僅顯示不同。存儲數據庫建議用 BIGINT UNSIGNED 或存字符串。

應用場景

  • IP 白名單/黑名單:Set 存儲 ipToLong(),O(1) 判斷。
  • CIDR 範圍檢查:ipInt >= network && ipInt <= broadcast。
  • IP 地理位置索引:long start, end, geoId 區間樹/B+樹查詢。
  • 網絡設備配置下發:整數運算比字符串解析快 10 倍以上。

總結

掌握 >>>>、& 0xFF、<< 位運算組合,即可在 Java 中高效實現 IPv4 與整數雙向轉換。IPv4Util 封裝了校驗、CIDR/掩碼雙模式範圍解析、字節數組中轉,可直接納入項目公共庫。

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