2011-12-19 8 views
8

Come è possibile verificare se due IP si trovano nella stessa rete in base alla subnet mask?Test con Java se due IP si trovano nella stessa rete

Ad esempio, ho gli IP 1.2.3.4 e 1.2.4.3: Entrambi si trovano nella stessa rete se la maschera è 255.0.0.0 o 255.255.0.0 o anche 255.255.248.0 ma non se la maschera è 255.255.255.0.

risposta

5

Abbastanza semplice: mask & ip1 == mask & ip2 - è necessario interpretare tutti gli IP come un unico numero, ma dovrebbe essere ovvio.

+0

Ma come ottenere la maschera? E funziona anche per IPv6? – xZise

+0

@xZise La maschera è la maschera di sottorete. E sicuramente funzionerà per IPv6 altrettanto bene - solo una notazione diversa rispetto a IPv4. Ma alla fine basta usare la subnet mask per mascherare la parte di rete dell'IP e quindi confrontarle tra loro. – Voo

+0

Ma come ottenere la maschera di sottorete dal programma stesso? – xZise

14

provare questo metodo:

public static boolean sameNetwork(String ip1, String ip2, String mask) 
throws Exception { 

    byte[] a1 = InetAddress.getByName(ip1).getAddress(); 
    byte[] a2 = InetAddress.getByName(ip2).getAddress(); 
    byte[] m = InetAddress.getByName(mask).getAddress(); 

    for (int i = 0; i < a1.length; i++) 
     if ((a1[i] & m[i]) != (a2[i] & m[i])) 
      return false; 

    return true; 

} 

e usarlo in questo modo:

sameNetwork("1.2.3.4", "1.2.4.3", "255.255.255.0") 
> false 

EDIT:

Se hai già gli IP come InetAddress oggetti:

public static boolean sameNetwork(InetAddress ip1, InetAddress ip2, String mask) 
throws Exception { 

    byte[] a1 = ip1.getAddress(); 
    byte[] a2 = ip2.getAddress(); 
    byte[] m = InetAddress.getByName(mask).getAddress(); 

    for (int i = 0; i < a1.length; i++) 
     if ((a1[i] & m[i]) != (a2[i] & m[i])) 
      return false; 

    return true; 

} 
+0

Bella soluzione: evita di dover analizzare personalmente la stringa. – Voo

+0

Ho già gli stessi IP come InetAddresses, quindi al massimo devo analizzare la maschera. – xZise

+0

@xZise Ho modificato la mia risposta in modo che corrisponda al tuo ultimo commento. Si noti che se la maschera è uguale per tutti i confronti, sarebbe meglio calcolare il suo indirizzo byte [] solo una volta e riutilizzarlo –

0

questa soluzione funzionerà anche con IPv4/IPv6.

static boolean sameNetwork(final byte[] x, final byte[] y, final int mask) { 
    if(x == y) return true; 
    if(x == null || y == null) return false; 
    if(x.length != y.length) return false; 
    final int bits = mask & 7; 
    final int bytes = mask >>> 3; 
    for(int i=0;i<bytes;i++) if(x[i] != y[i]) return false; 
    final int shift = 8 - bits; 
    if(bits != 0 && x[bytes]>>>shift != y[bytes]>>>shift) return false; 
    return true; 
} 
static boolean sameNetwork(final InetAddress a, final InetAddress b, final int mask) { 
    return sameNetwork(a.getAddress(), b.getAddress(), mask); 
} 
Problemi correlati