CS_LEVEL_16_SOLUTION - OnlyCook/abitur-elite-code GitHub Wiki

Level 16 – Musterlösung: Paket-Validierung (Struktogramm)

Lösung

public class DatenPaket
{
    private int[] inhalt;
 
    public DatenPaket(int[] daten)
    {
        this.inhalt = daten;
    }
 
    public int[] GetInhalt()
    {
        return inhalt;
    }
}
 
public class NetzwerkKnoten
{
    private string knotenId;
 
    public NetzwerkKnoten(string id)
    {
        this.knotenId = id;
    }
 
    public int ValidierePaket(DatenPaket p)
    {
        int[] daten = p.GetInhalt();
 
        if (daten.Length < 3)
        {
            return -1;
        }
        else
        {
            int summe = 0;
            int i = 1;
 
            while (i < daten.Length - 1)
            {
                summe += daten[i];
                i++;
            }
 
            int pruefsumme = summe % 256;
 
            if (pruefsumme == daten[daten.Length - 1])
            {
                return daten[0];
            }
            else
            {
                return -2;
            }
        }
    }
}

Erklärung

Struktogramme lesen und umsetzen

Das Kernthema dieses Levels ist die Übersetzung eines Nassi-Shneiderman-Diagramms (Struktogramm) in Code. Im Abitur bekommst du solche Diagramme häufig als Strukturvorgabe – deine Aufgabe ist es, sie 1:1 in C# zu überführen, ohne die Logik zu verändern.

Das Struktogramm wurde hier als Java-Code durch Structorizer exportiert:

daten = Inhalt des DatenPakets;
if (weniger als 3 Elemente in daten?) { ergebnis = -1; }
else {
    summe = 0; i = 1;
    while (solange i kleiner als Elemente in daten - 1) {
        summe = summe + daten[i];
        i = i + 1;
    }
    pruefsumme = summe % 256;
    if (pruefsumme == letztes Element in daten?) { ergebnis = daten[0]; }
    else { ergebnis = -2; }
}

Pseudo-Beschreibungen wie „weniger als 3 Elemente in daten" musst du in konkreten C#-Code übersetzen: daten.Length < 3. Alles andere – die Reihenfolge der Blöcke, die Schachtelung, die Variablennamen – übernimmst du direkt aus dem Diagramm.


Array-Länge und Indexzugriff

Arrays haben in C# die Eigenschaft .Length, die die Anzahl der Elemente zurückgibt. Verwechsle das nicht mit Listen, die .Count verwenden.

daten.Length             // Anzahl der Elemente
daten[0]                 // erstes Element (Header/Paket-ID)
daten[daten.Length - 1]  // letztes Element (Prüfsumme)

Das Paket-Format laut Aufgabe:

Index Inhalt
0 Header (Paket-ID)
1 bis Length - 2 Nutzdaten (Payload)
Length - 1 Prüfsumme

Ein Paket braucht mindestens Header + ein Datenbyte + Prüfsumme, also mindestens 3 Elemente – daher die erste Prüfung daten.Length < 3.


Die while-Schleife

Das Struktogramm schreibt explizit eine while-Schleife vor. Der Unterschied zu foreach: Bei while steuerst du den Zähler selbst, was hier nötig ist, weil wir gezielt nur die Indizes 1 bis Length - 2 summieren wollen.

int i = 1;
while (i < daten.Length - 1)
{
    summe += daten[i];
    i++;
}
  • Start bei Index 1: Index 0 ist der Header, der nicht zur Prüfsumme gehört.
  • Ende bei daten.Length - 1 (exklusiv): Das letzte Element ist die gespeicherte Prüfsumme – die rechnen wir natürlich nicht mit ein.
  • i++ ist die Kurzform von i = i + 1, genau wie im Struktogramm.

Modulo und Prüfsummenvergleich

int pruefsumme = summe % 256;

Der Modulo-Operator % gibt den Rest einer ganzzahligen Division zurück. summe % 256 stellt sicher, dass das Ergebnis immer im Bereich 0–255 bleibt – also in den Wertebereich eines einzelnen Bytes passt. Das ist ein typisches Muster bei einfachen Netzwerkprotokollen.

Anschließend wird der berechnete Wert mit dem letzten Element des Arrays verglichen:

if (pruefsumme == daten[daten.Length - 1])
{
    return daten[0];  // Validierung erfolgreich -> Paket-ID zurückgeben
}
else
{
    return -2;        // Prüfsumme stimmt nicht
}

Die Methode gibt also drei mögliche Werte zurück: -1 (Paket zu kurz), -2 (Prüfsumme falsch) oder die Paket-ID aus daten[0] (alles korrekt). Das ist ein im Abitur häufig gesehenes Muster: eine Methode, die im Fehlerfall negative Sentinel-Werte zurückgibt.


DatenPaket – Array als Attribut

public DatenPaket(int[] daten)
{
    this.inhalt = daten;
}

Das übergebene Array wird direkt als Referenz gespeichert. GetInhalt() gibt es wieder zurück – NetzwerkKnoten kann dann direkt darauf arbeiten. Strukturell nichts Neues, aber ein wichtiger Baustein: Die Logik sitzt im NetzwerkKnoten, die Daten im DatenPaket. Saubere Trennung von Daten und Verarbeitung.dentisch. Beide Varianten sind im Abitur akzeptiert.