assignments/Assignment_012/readme.md

180 lines
7.4 KiB
Markdown

# IP-Adressen
**🎓 Benotetes Assignment 🎓**
📆 **Fällig: 23.06.2026** 📆
Mittlerweile haben Sie sich mit den Aliens angefreundet. Allerdings müssen sie demnächst zurück nach Hause.
"Es tut uns leid, aber mir müssen gehen"
Sie wollen aber weiterhin mit Ihren neuen Freunden im Kontakt bleiben.
"Müsst ihr wirklich gehen?"
Dann schlugen die Aliens etwas vor:
"Ja, aber wir können unsere Computer in einem Netzwerk verbinden, um weiterhin zu kommunizieren".
Diese Idee klang super, bis Sie feststellten, dass sie nicht wissen, wie man
Computer in einem Netzwerk verbindet.
"Aber wie soll das gehen?"
"Wir brauchen dafür nur IP-Adressen im selben Netzwerk"
Dafür brauchen Sie aber ein Tool, mit dem Sie IP-Adressen in einem Netzwerk
berechnen können.
## Paket
Gehen Sie in das Paket [pr2.collections.ip](../sources/src/main/java/pr2/collections/ip/).
## Implementierung
Im Paket
[pr2.collections.ip.iputils](../sources/src/main/java/pr2/collections/ip/iputils/) befinden sich folgende Inhalte:
* `IPAdress` -> Eine Klasse
* `IPFormatter` -> Ein Interface
* `IPParser` -> Ein Interface
* `IPInformation` -> Ein Enum
* `IPParseException` -> Eine Ausnahme
Und noch eine `Main` im darüberliegendem Paket.
Zur Information über IP-Adressen:
* Eine IP-Adresse besteht aus 2 Teilen: die Adresse selbst sowie die Subnetzmaske
* Die Subnetzmaske beginnt immer links, und eine Folge von 1 und danach nur noch 0. Zum Beispiel `11110000` wäre eine Subnetzmaske (nicht vollständig, geht um das Konzept), `10100001` aber nicht.
* Die Subnetzmaske wird üblicherweise mit `/X` angegeben, wo `X` die Anzahl an Bits ist, die auf 1 sind.
* Die Subnetzmaske ist immer genauso lang wie die IP-Adresse (in bytes)
* Die Netzwerkadresse wird berechnet, indem alle Host-Bits auf 0 gesetzt werden, bsp: `10101010` als IP und `11110000` als Subnetzmaske ergeben `10100000` als Netzwerkadresse.
* Die Broadcastadresse wird berechnet, indem alle Host-Bits auf 1 gesetzt werden, bsp: `10101010` als IP und `11110000` als Subnetzmaske ergeben `10101111` als Broadcastadresse.
### `Main`
Diese Klasse hat eine `main`-Methode, welche den Nutzer auf der Konsole nach einer IP-Adresse frägt, diese einliest, verarbeitet und dann das Ergebnis auf der Konsole ausgibt. Ein Beispiel könnte wie folgt aussehen:
```
Bitte gib eine IP-Adresse ein: 192.168.0.1/30
```
```
IP-Adresse: 192.168.0.1/30
Network: 192.168.0.0/30
Broadcast: 192.168.0.3/30
Range: 192.168.0.1/30 - 192.168.0.2/30
Verfügbare Adressen:
192.168.0.1/30
192.168.0.2/30
```
Sie dürfen gerne beliebig rumspielen, aber eine simple Ausgabe wie im obigen Beispiel genügt.
### `IPAddress`
Dieser Klasse fehlt einiges:
* `getNetworkAddress` Implementierung
* `getBroadcastAddress` Implementierung
* `addHostByte` Implementierung
* `prettyFormat` Implementierung
* `iterator` Implementierung
* Konstruktoren
In den Javadocs können Sie sehen, was die Methoden jeweils tun sollen. Es soll neben dem Copy-Konstruktor auch einen Konstruktor geben, der eine **verarbeitbare Darstellung einer IP-Adresse** sowie einen passenden `IPFormatter` bekommt.
Überlegen Sie sich gut, wie eine **verarbeitbare Darstellung einer IP-Adresse** aussehen sollte.
Dann zum Iterator: dieser soll über die IP-Adressen im Range iterieren, sprich die _Netzwerkadresse_ sowie die _Broadcastadresse_ **nicht** mit einbegriffen. Sie dürfen eine Innere-Klasse oder seperate Klasse verwenden, beide sollen allerdings von außen nicht sichtbar sein!
Dann noch ein Beispiel-Output für die `prettyFormat`-Methode:
```
IP-Adresse: 192.168.0.1/30
Network: 192.168.0.0/30
Broadcast: 192.168.0.3/30
Range: 192.168.0.1/30 - 192.168.0.2/30
Verfügbare Adressen:
192.168.0.1/30
192.168.0.2/30
```
### `IPFormatter`
Diesem Interface fehlt noch eine Methode `format`. Diese Methode soll einen String als Rückgabewert zurückgeben. Überlegen Sie sich geeignete Parameter.
### `IPParser`
Diesem Interface fehlt noch eine Methode `parse`. Diese Methode soll einen String übergeben bekommen und eine für die `IPAddress` **verarbeitbare Darstellung der IP-Adresse** zurückgeben. Überlegen Sie sich einen geeigneten Rückgabewert.
### `IPInformation`
Dieses Enum soll Optionen für das `prettyFormat` der `IPAddress` angeben. Sie dürfen hier auch gerne Methoden hinzufügen, es dürfen aber **keine** Konsolen-Ausgaben getätig werden.
Es sollte für folgendes Optionen geben:
* Die IP-Adresse
* Die Netzwerkadresse der IP-Adresse
* Die Broadcast-Adresse der IP-Adresse
* Den Range der IP-Adresse (**Netzwerkadresse+1** - **Broadcastadresse-1**)
* Alle IP-Adressen im Range ausgeben
### `IPParseException`
Diese Klasse ist bereits implementiert. Sie dürfen diese gerne ändern, müssen dies aber nicht.
### Weiteres
Ebenfalls fehlt jeweils eine Klasse, die `IPFormatter` bzw. `IPParser` implementieren. Erstellen Sie dafür entsprechend eine `IPv4Formatter` und `IPv4Parser` Klasse und implementieren Sie diese. Es sollen gängige IPv4-Adressen verarbeitbar / ausgegeben werden können, zum Beispiel `192.168.0.1/24`.
### Bonus [+25 Punkte]
Wer Bonus-Punkte möchte, darf zusätzlich einen `IPv6Formatter` und `IPv6Parser` erstellen und implementieren. Die Punkte gibt es allerdings **nur**, wenn alle folgende Formate sowohl eingegeben als auch ausgegeben werden können:
* `::/24`
* `::1/24`
* `1::1/24`
* `1:1::1/24`
* `1111:1111:1111:1111:1111:1111:1111:1111/24`
**Informationen**
* Das sind nur Beispiele für die Formate, natürlich sollten alle möglichen IPv6-Adressen in diesen Formaten funktionieren.
* Es sollte **keine** andere Klasse angepasst werden, dass IPv6 funktioniert, mit Ausnahme der `Main`
Und natürlich soll das ganze dann auch in der `Main` funktionieren, zum Beispiel:
```
Bitte gebe eine IP-Adresse ein: ::1/126
IP-Adresse: ::1/126
Network: ::/126
Broadcast: ::3/126
Range: ::1/126 - ::2/126
Verfügbare Adressen:
::1/126
::2/126
```
## Tests
Überprüfen Sie die Funktionalität Ihrer Implementierung mit entsprechenden JUnit-Tests und weisen Sie mit diesen Tests nach, dass die implementierten Operationen richtig funktionieren. Testen Sie alle Methoden und Konstruktoren (die `prettyFormat`-Methode müssen Sie nicht testen).
**Abgabe**: Source-Code der Tests als `IPTest`.
## Abgabe
Alle Abgaben für die Vorlesung erfolgen über `git` und das Ihnen zugeordnete Repository.
Hierzu gehen Sie wie folgt vor:
1. Öffnen Sie eine Kommandozeile (Terminal).
2. Gehen Sie in Ihr Working Directory.
3. Rufen Sie mit `bin/submit.sh` das Skript auf, das die Lösungen testet und kompiliert. Wenn Maven eine Fehlermeldung zeigt, beheben Sie diese zuerst, bevor Sie mit dem nächsten Schritt fortfahren.
4. Wenn Sie Meldung "✅ Projekt gebaut" bekommen, checken Sie Ihre Änderungen in `git` **auf der Kommandozeile** ein (comitten), d.h. mit `git add` und `git commit`. Verwenden Sie **nicht** Eclipse für diesen Schritt.
5. Rufen Sie mit `bin/submit.sh` erneut das Skript auf. Wenn alles klappt, bekommen Sie die Anzeige "✅ Aktuelle Lösungen eingereicht" und Ihre Lösung ist im System angekommen.
6. Überprüfen Sie über das Web-Frontend, ob alles so im Repository liegt, wie Sie es erwarten.
**Erinnerung**: Denken Sie daran, dass Sie alle **öffentlichen Methoden** mit entsprechender **Javadoc** versehen müssen. **Ausgaben** auf und **Eingaben** von der Konsole sind nur dann erlaubt, wenn der Aufgabentext es explizit verlangt.