2016-01-11 13 views
5

Come rilevare se c'è un'intersezione tra due oggetti Golang net.IPNet?Come rilevare se due oggetti Golang net.IPNet si intersecano?

Cioè, come controllare sia se la prima rete è sottorete della seconda O se la seconda rete è sottorete del primo.

Does Go fornisce una funzione di utilità pronta per questo compito specifico?

Vedere il codice di prova di seguito.

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 
} 

eseguire sul Go Playground

risposta

4

Se (come i vostri casi di test sembrano implicare) non si preoccupa di quale lato contiene i quali, ma solo che c'è sovrapposizione, questo dovrebbe essere sufficiente.

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

In che modo? Abbastanza sicuro che il valore finale nell'IP non sarà mai ** lo stesso ... È necessario confrontare le maschere di sottorete o una sottostringa dell'IP. – evanmcdonnal

+2

@evanmcdonnal Non sono sicuro di cosa intendi. IPNet.IP è il numero di rete, non l'IP che è stato analizzato, e abbiamo solo bisogno di contenimento. – dahc

+0

Dovrebbe funzionare bene in quel caso. Credo di aver bisogno di leggere i documenti. – evanmcdonnal

3

È possibile utilizzare il fatto che gli indirizzi IP (net.IP) e maschere di rete (net.IPMask) sono semplicemente Byte di fette ([]byte) che contengono gli indirizzi IP binari. È possibile utilizzare i soliti bit a bit-operatori gli indirizzi di rete e le loro maschere per stabilire se una rete è una sottorete di un altro:

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 
} 

Questa funzione non è presente alcuni controlli di integrità di base (ad esempio, si spezzerebbe quando passò un IPv4 e un indirizzo IPv6), ma l'esempio dovrebbe essere sufficiente per ottenerne l'essenza.

Succede in tutti i casi di test dalla domanda, tranne la prima. Dopotutto, 1.1.0.2/16 non è in realtà una sottorete di 1.1.1.1/24 (è il contrario).

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

+0

"Succede in tutti i casi di test dalla tua domanda, tranne il primo, ma dopo tutto, 1.1.0.2/16 non è in realtà una sottorete di 1.1.1.1/24 (è il contrario)." Grazie. Tuttavia, ho davvero bisogno di rilevare qualsiasi intersezione, se n1 è subnet di n2, o se n2 è subnet di n1. Aggiornerò la domanda per chiarire questo punto. – Everton

Problemi correlati