簡體   English   中英

將ip數組轉換為java中最小的cidr子網列表

[英]Convert ip array to smallest cidr subnet list in java

我有一個像下面的IP數組,我想將其轉換為最小的cidr子網列表。 Java中是否有一個庫?

例如:

1.1.3.0
1.1.3.1
1.1.3.2
1.1.3.3
..
1.1.3.254
1.1.3.255
1.2.3.0
1.2.3.1
1.2.3.2
1.2.3.3
..
1.2.3.254
1.2.3.255
1.3.3.0
1.3.3.1
1.3.3.2
1.3.3.3
..
1.3.3.128
1.3.3.129

轉換成

1.1.3.0/24
1.2.3.0/24
1.3.3.0/25
1.3.3.128/31

提前致謝。

我不知道Java中是否有可用的庫。 事實上,我對Java知之甚少:)但我可以給你一個解決問題的算法,如果有任何幫助的話。

1)將ip地址轉換為整數對,其中第一個整數是ip地址的二進制表示(abcd - > a << 24 + b << 16 + c << 8 + d),第二個整數是32 (也就是說,最初每個地址都是它自己的子網[1])。

2)對對列表進行排序。

3)現在掃描排序列表,從第二對開始。 對於每一對,如果您可以將它與前一對組合,請執行此操作並繼續嘗試,直到盡可能長時間組合。 如果bits1 == bits2base2 ^ base1 == 1 << (32 - bits1) [base2, bits2]則可以組合兩對[base1, bits1][base2, bits2] 在這種情況下,組合是[base1, bits1 - 1]

4)最后,將對轉換回CIDR表示法:第一個整數是子網的基數(當轉換回點分十進制時),第二個整數是位寬。

步驟2和3都是O(n log n)

腳注1:在您的示例中,您不包含最后一個字節為0的地址,這意味着我的算法將在您的測試用例中失敗。 您必須將它們添加到列表中。 這一點揭示了CIDR子網定義中的一個微妙但重要的細節:從技術上講,可能的最小子網是/ 30,因為該范圍的第一個和最后一個ip都是保留的。 因此/ 31將沒有有效的IP地址。 但是,人們經常使用術語CIDR子網來表示“識別一組IP地址的位掩碼”,就像它們用作過濾器表達式一樣。

為此,Java提供了一個庫。 開源IPAddress Java庫具有將地址合並到前綴塊子網的方法。 免責聲明:我是IPAddress庫的項目經理。

以下方法“merge”顯示代碼,依賴於庫中的方法mergeToPrefixBlocks:

static String[] merge(List<String> strs) {
    // convert first to address
    IPAddress first = new IPAddressString(strs.get(0)).getAddress();
    // convert remaining to address
    IPAddress others[] = strs.subList(1, strs.size()).stream().map(str -> new IPAddressString(str).getAddress()).toArray(IPAddress[]::new);
    // merge them all
    IPAddress[] blocks = first.mergeToPrefixBlocks(others);
    // convert back to strings
    return Arrays.stream(blocks).map(block -> block.toString()).toArray(String[]::new);
}

可以使用您的示例地址集演示該方法,如以下代碼所示:

ArrayList<String> strs = new ArrayList<>();
String firstPref = "1.1.3.";
String secondPref = "1.2.3.";
String thirdPref = "1.3.3.";
for(int i = 0; i <= 255; i++) {
    strs.add(firstPref + i);
    strs.add(secondPref + i);
}           
for(int i = 0; i <= 129; i++) {
    strs.add(thirdPref + i);
}
String result[] = merge(strs);
System.out.println("blocks are " + Arrays.asList(result));

輸出是:

blocks are [1.3.3.128/31, 1.3.3.0/25, 1.1.3.0/24, 1.2.3.0/24]

試着:

public class Test {
    public static void main(String[] args) {
        String[] ipArray1 = new String[]{"1.1.3.1", "1.1.3.3", "1.1.3.2", "1.3.3.254"};
        String[] ipArray2 = new String[ipArray1.length];
        for(int i=0; i < ipArray1.length; i++) {
            String temp = ipArray1[i];
            ipArray2[i] = temp.substring(0,6) + "0/24";
        }
        for(String  ip : ipArray2) {
            System.out.println(ip);
        }
    }
}

輸出:

    1.1.3.0/24
    1.1.3.0/24
    1.1.3.0/24
    1.3.3.0/24

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM