IP-Adressenpool berechnen

Mampf

Mitglied
Also, die Zahl die bei negativer Netzmaske rauskommt ist die maximale letzte Stelle der IP? Aber ist nicht der maximal mögliche Wert generell 255?

Außerdem habe ich zwecks besserem Verständnis noch eine kleine Frage zu longAsIpStr, und zwar da, wo wir das Array füllen.
Wenn ich das jetzt richtig verstanden haben, ist die Vorgangsweise so, dass wir zunächst die letzten 8 bits des long hernehmen, in die letzte Stelle des Arrays schreiben, und dann, indem wir 8 bits nach rechts shiften, die letzten 8 bits rauskicken und die vorletzten 8 an die Stelle der letzten setzen (und das dann noch zwei mal). Ist das so korrekt?
 
N

nillehammer

Gast
Also, die Zahl die bei negativer Netzmaske rauskommt ist die maximale letzte Stelle der IP?
Nein, das ist die maximale Anzahl der IPs in dem jeweiligen Subnetz. Die maximale letzte Stelle ist die Summe von niedgrigster IP plus der Anzahl.
Aber ist nicht der maximal mögliche Wert generell 255?
Nein. Bei den "Standard"-Größen (z.B. 255.255.255.0) ist es zufällig so. Nimm aber mal folgendes Netz: 10.1.2.0/255.255.255.128 Da ist die höchste Adresse die .127

Ist das so korrekt?
Ja absolut.
 

Mampf

Mitglied
Also jetzt weiß ich dann schon mal die erste IP + die Möglichkeiten. Das heißt theoretisch könnte ich jetzt den String mit der niedrigsten IP-Nummer hernehmen, die letzte Nummer in einen int verwandeln, dann die Möglichkeiten dazurechnen, und anschließend die ersten drei Werte des Strings hernehmen und als vierten die letzte Nummer + Möglichkeiten nehmen.

Wenn ich das jetzt so abtippe kommt mir das aber etwas umständlich vor... gibt es da vielleicht eine elegantere Methode?
 
N

nillehammer

Gast
Also jetzt weiß ich dann schon mal die erste IP + die Möglichkeiten. Das heißt theoretisch könnte ich jetzt den String mit der niedrigsten IP-Nummer hernehmen, die letzte Nummer in einen int verwandeln, dann die Möglichkeiten dazurechnen, und anschließend die ersten drei Werte des Strings hernehmen und als vierten die letzte Nummer + Möglichkeiten nehmen.
Nein, Du must die niedrigste IP als long wert nehmen, dazu die Anzahl addieren und dann erst mittels longAsIpStr die Ausgabe erzeugen.
 

Mampf

Mitglied
Also irgendwas funktioniert da nicht richtig...

[Java]public static String outputSubnetValue(String ip, String netmask) {

String resultStr = "";

long ipLong = ipStrAsLong(ip);
long netmaskLong = ipStrAsLong(netmask);
long netpart = ipLong&netmaskLong; //IP mit Netzmaske verknüpfen, hiermit wird der Netzwerkteil der IP bestimmt

long lowest = netpart + 1; //1 dazuzählen, weil der Netzwerkteil = niedrigste Nummer ist, und diese nicht vergeben werden darf.
int netmaskInt = (int) netmaskLong; //durch den downcast der netmask zu int wird die negative Anzahl der Möglichkeiten gefunden (Zweierkomplement)
netmaskInt = Math.abs(netmaskInt); //Anzahl positiv machen
long highest = netpart + netmaskInt;


resultStr=(longAsIpStr(lowest) + " bis " + longAsIpStr(highest));

return resultStr;

}[/Java]

Hab jetzt schon herumprobiert, aber irgendetwas läuft da schief.
 
N

nillehammer

Gast
Sieht eigentlich gut aus. Ich würde nur zwei Zeilen ändern. Zeile 9 löschen und in Zeile 15:
[Java]
resultStr=(longAsIpStr(netpart +1 ) + " bis " + longAsIpStr(highest -1));
[/Java]
So müsste es passen. Was bekommst Du denn für eine Ausgabe?
 
Zuletzt bearbeitet von einem Moderator:
N

nillehammer

Gast
So, ich habe Deinen Code gerade genommen und meine Änderungen eingebaut. So scheint er zu funktionieren. Wo gefällt Dir was nicht?
 
N

nillehammer

Gast
So nochmal ich. Ein kleiner Fehler ist doch noch drinnen. Er hat statt der höchst möglichen Host-IP immer die Broadcastadresse ausgegeben.

Dadurch, dass wir nach int gecastet haben, erhalten wir zwar die Anzahl möglicher IPs, aber dazuaddieren dürfen wir nur immer eins weniger bzw wir müssen für die Angabe der höchst möglichen Host-IP zwei abziehen. Mit der folgenden Zeile ist dann alles korrekt:
[Java]
resultStr=(longAsIpStr(netpart + 1) + " bis " + longAsIpStr(highest -2));
[/Java]
 

Mampf

Mitglied
Jap, so läuft's :D

Das Problem war, dass irgendetwas bei der Berechnung von highest schief lief und somit der dritte Wert der IP geändert wurde.
Da war dann z.B IP von 192.168.1.1 bis 192.168.2.1 (was so natürlich nicht stimmt).

Das heißt, jetzt noch die letzte Methode ordentlich kommentieren und dann ist das Programm fertig!

Ich möchte mich nochmal ganz herzlich für deine Hilfe und Geduld bedanken, das war echt toll :D
Außerdem war dieses Programm eine der für mich lehrreichsten Erfahrungen in Java überhaupt. Danke!
 
N

nillehammer

Gast
Da war dann z.B IP von 192.168.1.1 bis 192.168.2.1 (was so natürlich nicht stimmt).
Stimmt, so eine Range ist Quatsch. Bei "großen" Netzmasken kann es aber schon Ranges geben, wo sich die dritte oder sogar die zweite Stelle der IP ändern. Z.B. bei dieser Kombination: 192.168.0.0/255.255.128.0
Ich möchte mich nochmal ganz herzlich für deine Hilfe und Geduld bedanken, das war echt toll
Außerdem war dieses Programm eine der für mich lehrreichsten Erfahrungen in Java überhaupt. Danke!
Gern geschehen. Hat mir sehr viel Spaß gemacht. Und ich hab sogar auch was dabei gelernt (nämlich das final vor statischen Methoden Blödsinn ist.)
 
Zuletzt bearbeitet von einem Moderator:
N

nillehammer

Gast
...aber durch dieses Programm wieder einen dicken Boost bekommen ^^
Super, sei bitte noch so nett, wenn Du mit den Kommentaren fertig bist, dass Du dann noch mal den Code der kompletten Klasse postest. Dann kann man das Werk nochmal in seiner ganzen Pracht bewundern.:toll:
 

Mampf

Mitglied
Gerne:

Java:
package uebung2;

public final class IpConverter {
//Author: Paul W******
    
    private static final String SPLIT_EXP = "\\."; //Diese Konstante wird später benötigt, um den String zu splitten.
    public static final long BITMASK = 255; //Die Bitmaske wird später zum Verknüpfen gebraucht.
   
      /****************************************************************************************************
      * ipStrAsLong: Methode um eine IP-Adresse von einem String in einen long zu packen.                 *
      * Die vier durch Punkte getrennten Werte der IP (die vier Bytes) werden durch parsing               *
      * ermittelt und dann mit Hilfe des binären left-Shift Operators an die richtige Position            *
      * eines longs geschoben                                                                             *
      * Die vier letzten Bytes des long enthalten so den dazugehörenden Wert der IP.                      *
      * Ist z.B. die eingegebene IP 255.255.254.0, sieht die Aufteilung im long so aus:                   *
      * Byte 1 bis 4: Nicht benutzt und deswegen mit 0en belegt                                           *
      * Byte 5: 255                                                                                       *
      * Byte 6: 255                                                                                       *
      * Byte 7: 254                                                                                       *
      * Byte 8: 0                                                                                         *
      * Ein long (wie jeder andere Zahlentyp bei Java auch) kann sowohl dezimal als auch binär            *
      * interpretiert werden, je nachdem, was benötigt wird. Eine Umrechnung ist nicht erforderlich       *
      * Es wird ein long statt eines int verwendet, weil eine IP-Adresse vorzeichenlos ist.               *
      * In einem int wird das erste bit aber als Vorzeichen interpretiert (Stichwort: Zweier-Komplement). *
      *  Dies kann bei Berechnungen und dem Sortieren von Werten zu merkwürdigen Effekten führen.         *
      ****************************************************************************************************/
    public static long ipStrAsLong (final String ipStr) {
    
        long result = 0;
        final String[] strArray = ipStr.split(SPLIT_EXP); //String-Array erzeugen, String bei den Punkten splitten und ins Array schreiben
    
        for(int i = 0; i < strArray.length; i++) { //Array durchgehen
            int temp = Integer.parseInt(strArray[i]);
            result = result|temp; //long result bitweise mit int temp verknuepfen
            
            if(i != (strArray.length -1)) { //wenn nicht am Ende des Arrays angelangt, letzten Wert 8 Bits nach links shiften.
                result = result << 8;
                
            }
        }
    
        return result;
    }
      
      /*************************************************************************************************************    
      *longAsIpStr: Umgekehrte Methode von IpStrAsLong. Aus dem vorher gepackten long (der IP), werden zunächst    *
      * die Zahlenwerte ausgelesen und in das Array intArray gepackt. Der long wird von hinten nach vorne          *
      * durchgearbeitet, daher auch das Array von hinten gefüllt. Dies geschieht, indem zunächst alles bis auf das *
      * letzte Byte des longs 0 gesetzt wird. So bleibt die gesuchte Zahl übrig und wird ins Array geschrieben.    *
      * Dann wird ein Byte nach rechts geshiftet, und das vorletzte Byte wird an die vorletzte Stelle des Arrays   *
      * geschrieben. Der Shift- und Schreibvorgang geschieht dann noch zweimal, bis alle vier Zahlenwerte der IP   *
      * im Array stehen.                                                                                           *
      * In weiterer Folge wird das Array von vorne nach hinten durchgegangen und die Werte in den Ausgabestring    *
      * geschrieben, wobei Dezimalpunkte hinzugefügt werden, damit wieder eine IP entsteht.                        *
      *************************************************************************************************************/
    public static String longAsIpStr (long value) {
        
        int[] intArray = new int[4]; //Array zum Speichern der Werte.
        String resultStr= ""; //String, in dem das Ergebnis gespeichert wird.
        
        for(int i = intArray.length -1; i >= 0; i--) { 
            intArray[i] = (int) (value&BITMASK); // alle Werte bis auf das letzte Byte in value 0 setzen und von hinten die Positionen des Arrays füllen (downcast nach int)
            value = value >> 8; //8 bits nach rechts shiften
            
        }
        
        for(int i = 0; i < intArray.length; i++) { //Aus den ints im Array den String zusammenbauen.
            
            if(i == (intArray.length -1)) {
                
                resultStr = (resultStr + intArray[i]);
                
            }else {
                
                resultStr = (resultStr + intArray[i] + ".");
                
            }  
        }
          
        return resultStr;
    }
    
    /****************************************************************************************************
     * outputSubnetValue: Methode, um die kleinste und größte IP-Adresse aus einer eingegebenen IP      *
     * + Subnetzmaske zu ermitteln. Zunächst werden die beiden Strings mithilfe von ipStrAsLong() in    *
     * longs gepackt. Dann wird die IP mit der Netzmaske binär verknüpft, womit der Netzwerkteil der IP *
     * bestimmt wird. Dieser ist zugleich auch die Subnetznummer, die niedrigste IP ergibt sich aus     *
     * Subnetznummer + 1.                                                                               *
     * Daraufhin wird die Anzahl der möglichen IPs ausgerechnet, indem die Subnetzmaske als int         *
     * gedowncastet wird. Die Anzahl der möglichen IPs + die niedrigste IP ergibt dann die höchste IP +1*
     * , weil die Broadcast-Adresse nicht mitgerechnet werden darf. Die niedrigste und höchste IP werden*
     * schlussendlich in einen String geschrieben und als Rückgabewert zurückgegeben.                   *
     ***************************************************************************************************/
    public static String outputSubnetValue(String ip, String netmask) {
    
        String resultStr = "";
        
        long ipLong = ipStrAsLong(ip);
        long netmaskLong = ipStrAsLong(netmask);
        long netpart = ipLong&netmaskLong; //IP mit Netzmaske verknüpfen, hiermit wird der Netzwerkteil der IP bestimmt
        
        int netmaskInt = (int) netmaskLong; //durch den downcast der netmask zu int wird die negative Anzahl der Möglichkeiten gefunden (Zweierkomplement)
        netmaskInt = Math.abs(netmaskInt); //Anzahl positiv machen
        long highest = netpart + netmaskInt; //höchsten Wert der IP bestimmen, indem die Anzahl der möglichen IPs zur niedrigsten Adresse addiert wird
        
        	
        resultStr=(longAsIpStr(netpart +1 ) + " bis " + longAsIpStr(highest -2)); // die longs werden in Strings umgewandelt -> niedrigste + 1, weil .0 nicht vergeben werden darf
        return resultStr;                                                         //(Fortsetzung) höchste -2, weil Broadcast nicht vergeben werden darf
        
    }
}

Die UI:

Java:
package uebung2;


import iO.IO;




public class UI {


    public static void main(String[] args) {
        
        String netmask, ip;
        char repeat;
        
        do {
        
        IO.write("Geben Sie die Subnetzmaske des gewünschten IP-Pools ein: ");
        netmask = IO.readLine();
        
        IO.write("Geben Sie die IP-Adresse des gewünschten IP-Pools ein: ");
        ip = IO.readLine();
        
        String result = IpConverter.outputSubnetValue(ip, netmask);
        
        
        IO.writeLn("Der gesuchte IP-Pool lautet: " + result);
        
        IO.write("Noch eine Umwandlung? [j/n]: ");
        repeat = IO.read();
        IO.readLn();
        
        }while((repeat == 'j') || (repeat == 'J'));
        
    }
}
 

Neue Themen


Oben