Update of exercises
parent
4f7d44b12f
commit
281bb0dd1c
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Password-Qualität
|
||||||
|
|
||||||
|
**🎓 Benotetes Assignment 🎓**
|
||||||
|
|
||||||
|
📆 **Fällig: 14.04.2026** 📆
|
||||||
|
|
||||||
|
„War ja klar“, denken Sie sich, „die Aliens lügen wie gedruckt! Von wegen zurück auf die Erde...“
|
||||||
|
|
||||||
|
Ihre Implementierung der Zahlen zur Basis vier war der absolute Knaller und die Aliens sind mehr als glücklich, Ihre Implementierung in das neue Software-System einbauen zu können. Sie werden in Zukunft von den Außerirdischen nur noch ᎮᏈᏍᎹᏅᏇᏅᏅᎨ genannt, was so viel wie „Checker mit dem leckeren Gehirn“ bedeutet.
|
||||||
|
|
||||||
|
Da man einem Checker das Gehirn nicht aussaugt, ist auch Ihr Leben fürs Erste gerettet. Leider dürfen Sie aber auch nicht zurück auf die Erde, sondern müssen auf dem Raumschiff bleiben – Sie können einfach zu gut programmieren.
|
||||||
|
|
||||||
|
Eine Analyse des großen Cyberangriffs auf den Planeten der Aliens, die sich übrigens selbst Kryptonier nennen, hat gezeigt, dass neben dem von der KI generierten Code, mit all seinen Sicherheitslücken, auch schwache Passwörter ein Problem waren. Deswegen sollen Sie jetzt eine Software entwickeln, welche die Qualität von Passwörtern bewerten kann.
|
||||||
|
|
||||||
|
„Pah, Erstsemesterkram“, rufen Sie und sind im Geiste schon fertig, als das Kommandant der Aliens Sie zur Seite nimmt.
|
||||||
|
|
||||||
|
„Wir erwarten von dir ein modernes, objektorientiertes Design“, sagt es, „wir wollen in der Lage sein, neue Regeln jederzeit hinzuzufügen, ohne unser Hauptprogramm anpassen zu müssen. Das Hauptprogramm ist fertig und darf nicht verändert werden!“
|
||||||
|
|
||||||
|
Da die Kryptonier große Freunde von klarer Kommunikation sind, fügen sie noch hinzu „falls du dich nicht an die Regeln hälts, denk an dein Gehirn.“ Dabei schmatzen Sie wieder verdächtig.
|
||||||
|
|
||||||
|
## Paket
|
||||||
|
|
||||||
|
Gehen Sie in das Paket [pr2.vererbung.password](../sources/src/main/java/pr2/vererbung/password/).
|
||||||
|
|
||||||
|
## Implementierung
|
||||||
|
|
||||||
|
Alle Regeln befinde sich um Paket [pr2.vererbung.password.rules](../sources/src/main/java/pr2/vererbung/password/rules) und leiten von der abstrakten Klasse `Rule` ab.
|
||||||
|
|
||||||
|
Jedes Passwort wird in eine von drei Kategorien eingeordnet:
|
||||||
|
|
||||||
|
* `BAD` -> Passwort ist unbrauchbar
|
||||||
|
* `FAIR` -> Passwort ist nicht gut aber noch akzeptabel
|
||||||
|
* `GOOD` -> Passwort ist gut
|
||||||
|
|
||||||
|
Diese Bewertung wird als Zahl (siehe Konstanten in der Klasse `Rule`) repräsentiert.
|
||||||
|
|
||||||
|
Wenn mehrere Regeln kombiniert werden, gilt immer die schlechteste Bewertung.
|
||||||
|
|
||||||
|
Implementieren Sie Password-Prüfungen für folgende Tests, die alle von der abstrakten Klasse `Rule` abgeleitet sind:
|
||||||
|
|
||||||
|
* **Zeichensatz** (`RuleChars`): Das Password muss mindestens einen Großbuchstaben, einen Kleinbuchstaben, eine Zahl und ein Sonderzeichen enthalten, um gut zu sein (`GOOD`). Fehlt eine der Kategorien, ist es noch akzeptabel (`FAIR`), ansonsten schlecht (`BAD`).
|
||||||
|
* **Wörterbuch** (`RuleDictionary`): Das Password darf kein Wort aus einem Wörterbuch enthalten. Das Wörterbuch ist der Einfachheit halber als „mutti“, „papi“, „dackel“ und „password“ festgelegt. Groß- und Kleinschreibung haben keine Relevanz, d.h. „Mutti“ und „mutti“ sind beide verbotene Wörter.
|
||||||
|
* **Länge** (`RuleLength`): Das Passwort muss eine Mindestlänge von 8 Zeichen haben (`BAD`), oberhalb einer optimalen Länge von 12 ist es gut (`GOOD`), darunter `FAIR`.
|
||||||
|
* **Entropie** (`RuleEntropy`): Die Shannon Entropie des Passwortes muss in einem bestimmten Bereich liegen:
|
||||||
|
- `< 1.0`: Schlecht (`BAD`)
|
||||||
|
- `< 2.0`: Akzeptabel (`FAIR`)
|
||||||
|
- `>= 2.0`: Gut (`GOOD`)
|
||||||
|
* **Kombination** (`RuleCombined`): Beliebige Regeln können zu einer komplexeren Regel kombiniert werden. Für den Anfang werden einfach alle Regeln benutzt, um die Kombination zu realisieren.
|
||||||
|
|
||||||
|
*Achtung:* Die Klassen liegen in einem eigenen Paket und sind nicht von außerhalb des Paketes sichtbar.
|
||||||
|
|
||||||
|
Überschreiben Sie in jeder Ihrer Regelklassen die Methode `toString()`, welche den Namen der Regel und möglicherweise Zusatzinfos zur jeweiligen Regel ausgibt.
|
||||||
|
|
||||||
|
Instanzen der Regeln werden über die Klasse `RuleFactory` und deren Methode `createRule` erzeugt. Dort finden Sie Konstanten, welche die verschiedenen Regeln repräsentieren.
|
||||||
|
|
||||||
|
Eine Klasse `PasswordChecker` ist vorgegeben, bei der man ein Passwort auf der Konsole eingibt und die dann dieses Password gegen die verschiedenen Regeln prüft. Diese Klasse **dürfen Sie nicht verändern**, d.h. Ihre Lösung muss so gebaut sein, dass Sie mit der unveränderten Klasse funktioniert.
|
||||||
|
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
**Abgabe**: Source-Code der Tests als `PasswordCheckerTest`.
|
||||||
|
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
@ -21,6 +21,7 @@ Wichtige Einstellungen für Eclipse sind [hier](help/eclipse.md) beschrieben.
|
||||||
| 2. | 17.03.2026 | [Erster Commit](Assignment_002/readme.md) | **25.03.2026** |
|
| 2. | 17.03.2026 | [Erster Commit](Assignment_002/readme.md) | **25.03.2026** |
|
||||||
| 3. | 25.03.2026 | [Stein, Papier, Schere (, Echse, Spock)](Assignment_003/readme.md) | **31.03.2026** |
|
| 3. | 25.03.2026 | [Stein, Papier, Schere (, Echse, Spock)](Assignment_003/readme.md) | **31.03.2026** |
|
||||||
| 4. | 01.04.2026 | [Zahlen zur Basis 4](Assignment_004/readme.md) | **07.04.2026** |
|
| 4. | 01.04.2026 | [Zahlen zur Basis 4](Assignment_004/readme.md) | **07.04.2026** |
|
||||||
|
| 5. | 08.04.2026 | [Password-Qualität](Assignment_005/readme.md) | **14.04.2026** |
|
||||||
|
|
||||||
## 🏛️ Aufbau der Veranstaltung
|
## 🏛️ Aufbau der Veranstaltung
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// ###########################################
|
||||||
|
// ACHTUNG: SIE DÜRFEN DIESE KLASSE NICHT
|
||||||
|
// VERÄNDERN. SONST WIRD IHR GEHIRN
|
||||||
|
// AUSGESAUGT. SIE MUSS MIT IHREM
|
||||||
|
// PROGRAMM FUNKTIONIEREN,
|
||||||
|
// EINFACH SO.
|
||||||
|
//
|
||||||
|
// GRÜSSE, DIE ALIEN OVERLORDS
|
||||||
|
// ###########################################
|
||||||
|
package pr2.vererbung.password;
|
||||||
|
|
||||||
|
import pr2.vererbung.password.rules.Rule;
|
||||||
|
import pr2.vererbung.password.rules.RuleFactory;
|
||||||
|
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password-Checker der Aliens.
|
||||||
|
*/
|
||||||
|
public class PasswordChecker {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hauptmethode.
|
||||||
|
* @param args Kommandozeilenargumente.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
|
||||||
|
System.out.print("Bitte Password eingeben: ");
|
||||||
|
String input = scanner.nextLine();
|
||||||
|
|
||||||
|
for (int ruleCode : RuleFactory.AVAILABLE_RULES) {
|
||||||
|
Rule rule = RuleFactory.createRule(ruleCode);
|
||||||
|
int result = rule.checkPassword(input);
|
||||||
|
System.out.printf("Rule: %s -> %s\n", rule,
|
||||||
|
Rule.qualityToString(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\nKill all Humans!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package pr2.vererbung.password.rules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class.
|
||||||
|
*/
|
||||||
|
final class Helper {
|
||||||
|
|
||||||
|
private Helper() {
|
||||||
|
// no instances
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the Shannon Entropy over a character sequence.
|
||||||
|
*
|
||||||
|
* @param word the characters.
|
||||||
|
* @return the Shannon Entropy.
|
||||||
|
*/
|
||||||
|
public static double calcShannonEntropy(String word) {
|
||||||
|
int[] count = new int[Character.MAX_VALUE];
|
||||||
|
|
||||||
|
for (char c : word.toCharArray()) {
|
||||||
|
count[c]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
for (int e : count) {
|
||||||
|
if (e != 0) {
|
||||||
|
sum += e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double entropy = 0.0;
|
||||||
|
|
||||||
|
for (int e : count) {
|
||||||
|
if (e != 0) {
|
||||||
|
double p = (double) e / (double) sum;
|
||||||
|
entropy += (Math.log(p) / Math.log(2)) * p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -entropy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package pr2.vererbung.password.rules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all rules that can be used to check
|
||||||
|
* passwords against.
|
||||||
|
*/
|
||||||
|
public abstract class Rule {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points for a bad password.
|
||||||
|
*/
|
||||||
|
public static final int BAD = -20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points for a fair password.
|
||||||
|
*/
|
||||||
|
public static final int FAIR = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points for a good password-
|
||||||
|
*/
|
||||||
|
public static final int GOOD = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks a password and returns an evaluation in the form of
|
||||||
|
* points. Higher points indicate better passwords.
|
||||||
|
*
|
||||||
|
* @param password the password to check
|
||||||
|
* @return the result of the check
|
||||||
|
*/
|
||||||
|
public abstract int checkPassword(String password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the quality value as a string.
|
||||||
|
*
|
||||||
|
* @param quality the quality value. *
|
||||||
|
* @return a string representation.
|
||||||
|
*/
|
||||||
|
public static String qualityToString(int quality) {
|
||||||
|
return switch (quality) {
|
||||||
|
case BAD -> "bad";
|
||||||
|
case FAIR -> "fair";
|
||||||
|
case GOOD -> "good";
|
||||||
|
default -> "<unknown>";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the rule.
|
||||||
|
* @return the name of the rule.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return "<undefined>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package pr2.vererbung.password.rules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory class to create Rule objects.
|
||||||
|
*/
|
||||||
|
public class RuleFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entropy rule.
|
||||||
|
*/
|
||||||
|
public static final int ENTROPY = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length rule.
|
||||||
|
*/
|
||||||
|
public static final int LENGTH = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chars rule.
|
||||||
|
*/
|
||||||
|
public static final int CHARS = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dictionary rule.
|
||||||
|
*/
|
||||||
|
public static final int DICTIONARY = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All rules.
|
||||||
|
*/
|
||||||
|
public static final int ALL = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All available rules.
|
||||||
|
*/
|
||||||
|
public static final int[] AVAILABLE_RULES = {
|
||||||
|
ENTROPY,
|
||||||
|
LENGTH,
|
||||||
|
CHARS,
|
||||||
|
DICTIONARY,
|
||||||
|
ALL
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Rule createRule(int number) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package pr2.vererbung.password;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import pr2.vererbung.password.rules.*;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class PasswordCheckerTest {
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue