2016-01-11 9 views
5

Wie erkennt man, ob es eine Kreuzung zwischen zwei Golang net.IPNet Objekten gibt?Wie erkennt man, ob sich zwei Golang net.IPNet-Objekte schneiden?

das heißt, wie sowohl zu überprüfen, ob die erste Netzwerk-Subnetz der zweiten OR ist, wenn die zweite Netzwerk-Subnetz der ersten ist.

Bietet Go eine Dienstprogrammfunktion für diese spezielle Aufgabe?

Siehe Testcode unten.

package main 

import (
    "fmt" 
    "net" 
) 

func main() { 
    _, net1, _ := net.ParseCIDR("1.1.1.1/24") 
    _, net2, _ := net.ParseCIDR("1.1.0.2/16") 
    _, net3, _ := net.ParseCIDR("1.1.1.3/25") 
    _, net4, _ := net.ParseCIDR("1.2.0.4/16") 

    test(net1, net2, true) 
    test(net2, net1, true) 
    test(net1, net3, true) 
    test(net3, net1, true) 
    test(net1, net4, false) 
    test(net4, net1, false) 
} 

func test(n1, n2 *net.IPNet, expect bool) { 
    result := intersect(n1, n2) 
    var label string 
    if result == expect { 
     label = "good" 
    } else { 
     label = "FAIL" 
    } 
    fmt.Printf("test intersect(%v,%v)=%v expected=%v => %s\n", n1, n2, result, expect, label) 
} 

func intersect(n1, n2 *net.IPNet) bool { 
    return false // FIXME WRITEME 
} 

Run auf Go Playground

Antwort

4

Wenn (als Testfälle scheinen zu implizieren) Sie kümmern sich nicht um welche Seite enthält, die, sondern nur, dass es eine Überlappung ist, sollte dies ausreichend sein.

func intersect(n1, n2 *net.IPNet) bool { 
    return n2.Contains(n1.IP) || n1.Contains(n2.IP) 
} 
+0

Wie das? Ziemlich sicher, dass der letzte Wert in der IP ** nie ** der gleiche sein wird ... Sie müssen Subnetzmasken oder einen Teilstring der IP vergleichen. – evanmcdonnal

+2

@evanmcdonnal Ich bin mir nicht sicher, was du meinst. IPNet.IP ist die Netzwerknummer, nicht die IP, die geparst wurde, und wir brauchen nur die Eindämmung. – dahc

+0

Sollte in diesem Fall gut funktionieren. Ich denke, ich muss die Dokumente lesen. – evanmcdonnal

3

können Sie die Tatsache nutzen, dass IP-Adressen (net.IP) und netmasks (net.IPMask) sind nur Byte-Scheiben ([]byte), die die binären IP-Adressen enthalten. Sie können die üblichen bitweise-Operatoren auf die Netzwerkadressen und ihre Masken verwenden, um festzustellen, ob ein Netzwerk ein Subnetz eines anderen ist:

func intersect(n1, n2 *net.IPNet) bool { 
    for i := range n1.IP { 
     if n1.IP[i] & n1.Mask[i] != n2.IP[i] & n2.Mask[i] & n1.Mask[i] { 
      return false 
     } 
    } 
    return true 
} 

Diese Funktion einige grundlegende Plausibilitätsprüfungen fehlt (zum Beispiel, es würde brechen, wenn übergeben eine IPv4- und eine IPv6-Adresse), aber das Beispiel sollte ausreichen, um den Kern davon zu erhalten.

Es gelingt in allen Testfällen von Ihrer Frage, mit Ausnahme der ersten. Aber schließlich ist 1.1.0.2/16 nicht wirklich ein Subnetz von 1.1.1.1/24 (es ist umgekehrt).

https://play.golang.org/p/Kur5n2hfLg

+0

"Es ist in allen Testfällen von Ihrer Frage abgesehen von der ersten erfolgreich. Aber schließlich ist 1.1.0.2/16 nicht wirklich ein Subnetz von 1.1.1.1/24 (es ist umgekehrt)." Vielen Dank. Allerdings muss ich wirklich jeden Schnittpunkt erkennen, wenn n1 das Subnetz von n2 ist, oder wenn n2 das Subnetz von n1 ist. Ich werde die Frage aktualisieren, um dies zu verdeutlichen. – Everton