Algoritmo p/ gerar um Hashtable com todos ip's ,tendo como entrada "ip inicial" e "ip final"

3 respostas
D

Ola Galera do GUJ,

Alguém poderia me ajudar nesse empecilho que ta me queimando os poucos neuronios q restam,precisava de um
algoritmo com melhor performance para gerar um Hashtable com todos ip’s possiveis dentro do parametro,tendo como parametro de entrada um “ip inicial” e um “ip final”?

Consegui fazer um bem basico,que guarda em um hash chamado “primeiroOcteto” todos ip’s possiveis(com uma performance boa),porém quando tento colocar alguns parametros de “ip inicial” e um “ip final”,
perco totalmente a performance,criei varios, todos ficaram extremamentes demorados,alguns chegam a estourar memoria.

Se alguém conhecer aluma API que tem um método que trabalha dessa forma ou então que conheça um algoritmo, eu agradeço mto,

:slight_smile:

public class IpGenerator {

static Hashtable primeiroOcteto = new Hashtable();
static Hashtable segundoOcteto = new Hashtable();
static Hashtable terceiroOcteto = new Hashtable();
static Hashtable quartoOcteto = new Hashtable();

public static void main (String [] args){
	todosIps();
}


public static void todosIps(){
	int contArray4 = 0; 
	for(int i =0; i<256;i++){
		quartoOcteto.put(i,i);
	}
	for(int i =0; i<256;i++){
		terceiroOcteto.put(i,quartoOcteto);
	}
	for(int i =0; i<256;i++){
		segundoOcteto.put(i,terceiroOcteto);
	}
	for(int i =0; i<256;i++){
		primeiroOcteto.put(i,segundoOcteto);
	}	
}

}

3 Respostas

davidbuzatto

Para que uma Hashtable?

Olhe ai:
public class IP implements Comparable {

    private int oct1;
    private int oct2;
    private int oct3;
    private int oct4;

    public IP( int oct1, int oct2, int oct3, int oct4 ) {
        this.oct1 = oct1;
        this.oct2 = oct2;
        this.oct3 = oct3;
        this.oct4 = oct4;
    }

    public int getOct1() {
        return oct1;
    }

    public int getOct2() {
        return oct2;
    }

    public int getOct3() {
        return oct3;
    }

    public int getOct4() {
        return oct4;
    }

    @Override
    public String toString() {
        return oct1 + "." + oct2 + "." + oct3 + "." + oct4;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final IP other = (IP) obj;
        if (this.oct1 != other.oct1) {
            return false;
        }
        if (this.oct2 != other.oct2) {
            return false;
        }
        if (this.oct3 != other.oct3) {
            return false;
        }
        if (this.oct4 != other.oct4) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + this.oct1;
        hash = 59 * hash + this.oct2;
        hash = 59 * hash + this.oct3;
        hash = 59 * hash + this.oct4;
        return hash;
    }

    @Override
    public int compareTo(Object o) {
        if ( this.equals(o) ) {
            return 0;
        } else {
            IP other = ( IP ) o;
            if ( oct1 > other.getOct1() ) {
                return 1;
            } else if ( oct1 == other.getOct1() ) {
                if ( oct2 > other.getOct2() ) {
                    return 1;
                } else if ( oct2 == other.getOct2() ) {
                    if ( oct3 > other.getOct3() ) {
                        return 1;
                    } else if ( oct3 == other.getOct3() ) {
                        if ( oct4 > other.getOct4() ) {
                            return 1;
                        } else {
                            return -1;
                        }
                    } else {
                        return -1;
                    }
                } else {
                    return -1;
                }
            } else {
                return -1;
            }
        }
    }

}
import java.util.ArrayList;
import java.util.List;

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        IP ip1 = new IP( 203, 205, 200, 250 );
        IP ip2 = new IP( 203, 205, 200, 250 );
        System.out.println( gerarLista( ip1, ip2 ).size() );

    }

    public static List< IP > gerarLista( IP ipInicial, IP ipFinal ) {

        List< IP > lista = new ArrayList< IP >();

        // ipInicial é menor que ipFinal, gera lista
        if ( ipInicial.compareTo( ipFinal ) == -1 ) {
            
            // aqui que vai ficar o algoritmo para gerar a lista. Está errado esse que eu defini ;)
            for ( int oct1 = ipInicial.getOct1(); oct1 <= ipFinal.getOct1(); oct1++ )
                for ( int oct2 = ipInicial.getOct2(); oct2 <= ipFinal.getOct2(); oct2++ )
                    for ( int oct3 = ipInicial.getOct3(); oct3 <= ipFinal.getOct3(); oct3++ )
                        for ( int oct4 = ipInicial.getOct4(); oct4 <= ipFinal.getOct4(); oct4++ )
                            lista.add( new IP( oct1, oct2, oct3, oct4 ) );

            // são iguais, retorna uma lista com apenas um IP
        } else if ( ipInicial.compareTo( ipFinal ) == 0 ) {
            lista.add(
                    new IP( ipInicial.getOct1(),
                            ipInicial.getOct2(),
                            ipInicial.getOct3(),
                            ipInicial.getOct4() ) );
        }

        return lista;

    }

}
ViniGodoy

Cada octeto são 8 bits. Um int tem 4x8 bits. Logo, um endereço ip inteiro corresponde a um int.

Com isso, para gerar um ip atrás do outro, basta um simples for:

import java.util.Set;
import java.util.TreeSet;

public class IP implements Comparable&lt;IP&gt; {
	private int address;

	public IP(int oct1, int oct2, int oct3, int oct4) {
		address = (oct1 & 0xFF) &lt;&lt; 24;
		address += (oct2 & 0xFF) &lt;&lt; 16;
		address += (oct3 & 0xFF) &lt;&lt; 8;
		address += (oct4 & 0xFF);
	}
	
	private IP(int ip)
	{
		this.address = ip;
	}

	public int getOct1() {
		return (address &gt;&gt; 24) & 0xFF;
	}

	public int getOct2() {
		return (address &gt;&gt; 16) & 0xFF;
	}

	public int getOct3() {
		return (address &gt;&gt; 8) & 0xFF;
	}

	public int getOct4() {
		return address & 0xFF;
	}

	@Override
	public String toString() {
		return getOct1() + &quot;.&quot; + getOct2() + &quot;.&quot; + getOct3() + &quot;.&quot; + getOct4();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final IP other = (IP) obj;
		if (this.address != other.address) {
			return false;
		}
		return true;
	}

	@Override
	public int hashCode() {
		return address;
	}

	@Override
	public int compareTo(IP o) {
		return getAddress() == o.getAddress() ? 0 : 
			(getAddress() &gt; o.getAddress() ? 1 : -1);
	}
	
	private long getAddress()
	{
		return (long)(address & 0xFFFFFFFFL);
	}
	
	public static Set&lt;IP&gt; todosOsIps(IP min, IP max)
	{
		Set&lt;IP&gt; ips = new TreeSet&lt;IP&gt;();
		for (long i = min.getAddress(); i &lt; max.getAddress(); i++)
			ips.add(new IP((int)i));
		return ips;
	}
	
	public static Set&lt;IP&gt; todosOsIps()
	{
		Set&lt;IP&gt; ips = new TreeSet&lt;IP&gt;();
		for (int i = Integer.MIN_VALUE; i &lt; Integer.MAX_VALUE; i++)
			ips.add(new IP(i));
		return ips;
	}
}
public class Main {
	public static void main(String[] args) {
		IP ip1 = new IP( 200, 200, 200, 250 );  
		IP ip2 = new IP( 200, 200, 200, 255 );
		
		for (IP ip : IP.todosOsIps(ip1, ip2))
			System.out.println(ip);
	}
}

Entretanto, todos os IPs possíveis correspondem a 4.294.967.296 endereços.

No caso do Java, somos obrigados a converter ints para longs na hora de fazer o for pois não temos tipos unsigned. Em C++ isso não seria necessário.

É importante também entender os IPs como ints pq fica facílimo entender como aplicar máscaras de sub-rede. Para aplicar a mascara 255.255.255.0 (0xFFFFFF00) para um IP qualquer e obter o endereço da máquina na rede, basta fazer uma operação de AND. Se quiser obter o endereço da sub-rede, use um OR. Isso também explica aquelas máscaras que tem um número diferente de 0 no final.

Quanto ao Hastable. Ele geralmente associa uma chave a um valor. Não entendi porque usar nessa situação também. Outra coisa, o tipo HashTable já é desaconselhado desde o Java 1.2. Se for usar uma estrutura de hash, use a classe hashMap:
Map<Integer, String> mapa = new HashMap<Integer, String>();
Se quiser o mapa ordenado pela chave, use o TreeMap:
Map<Integer, String> mapa = new TreeMap<Integer, String>();

Nesse caso, a chave deve ser comparable, ou você deve fornecer um comparator para o mapa.

D

Desculpe pela demora de resposta pessoal,
tive problemas com meu Speedy ,essa me%#@.

Mas voltando ao que interessa , muito obrigado pela ajuda pessoal, a idéia do David me ajudou bastante,
mas a do ViniGodoy ,matou o problema, consegui implementar com um funcionamento muito agil e pratico,mesmo não usando os genericos,
Sei q eh uma tristeza usar o 1.4 fazer oq.

Quanto ao Hashtable,estou usando por solicitação de meu gerente,ja que o produto q estamos criando é para 1.4
e estamos usando objetos bem ogro mesmo ,pois eh um produto de caixinha,

Mas valeu mesmo ,abraços até mais.

Criado 27 de setembro de 2009
Ultima resposta 28 de set. de 2009
Respostas 3
Participantes 3