Block-Cipher (Schritt für Schritt)
Einleitung: Permutations-Chiffren
Hier ist ein verschlüsselter deutscher Text. Wer kann ihn entschlüsseln?
UCHBS ABETN ERDWE NURNU SORMT ERTIXLetzte Woche in den Übungen: Caesar-Chiffre – was war da das Prinzip? → Substitution (Buchstaben werden durch andere ersetzt)
Obiger Text ist NICHT mit Substitution verschlüsselt. Die Buchstaben sind noch alle da – sie stehen nur an anderen Stellen. Das nennt man Transposition oder Permutation.
Zum Entschlüsseln braucht man dieses Mal einen Schlüssel. Das ist ein deutsches Wort mit 5 Buchstaben.
Der Schlüssel ist: MACHT.
Das Keyword als Spaltenüberschriften aufschreiben:
M A C H T, aber so dass die Buchstaben alphabetisch sortiert sind, alsoA C H M T.Darunter den Ciphertext in 5er-Blöcken spaltenweise:
A C H M T U C H B S A B E T N E R D W E N U R N U S O R M T E R T I XJetzt sortieren wir die Spalten, sodass wieder das Wort MACHT in der ersten Zeile steht.
Dazu müssen wir umordnen: Spalte 1 (aktuell A) kommt an Position 2, Spalte 4 (aktuell M) kommt an Position 1. Nach Umordnung:
M A C H T B U C H S T A B E N W E R D E N N U R U M S O R T I E R T XJetzt zeilenweise lesen:
BUCHS TABEN WERDE NNURU MSORT IERTX
Das war mühsam per Hand. Jetzt programmieren wir das – aber andersherum: also die Verschlüsselung.
In unserem Programm geben wir die Permutation, also die Vertauschungen direkt als Zahlen ein (z.B. ‘12304’); die Verarbeitung des Schlüsselworts sparen wir uns. Das Prinzip bleibt gleich!
Phase 1: Problem verstehen
Einstiegsfragen
- Was bedeutet Verschlüsselung allgemein?
- Bei der Caesar-Verschlüsselung werden Buchstaben ersetzt. Was passiert hier stattdessen?
- Schauen wir uns ein Beispiel an. Was würde mit ‘ABC’ passieren, wenn wir die Positionen wie folgt tauschen: Position 0→2, 1→0, 2→1?
Durchspielen am Beispiel
“HELLOWORLD” mit Key “201”. Aus der Aufgabenstellung: Der Permutationsschlüssel “201” bedeutet: Position 0 geht nach 2, Position 1 geht nach 0, Position 2 geht nach 1.
1. String aufteilen:
HEL | LOW | ORL | D??
2. Was bedeutet Key "201"?
0 → 2
1 → 0
2 → 1
3. Ersten Block permutieren:
H E L Position: 0 1 2
↓ ↓ ↓
E L H Neue Pos: 2 0 1Phase 2: Grundgerüst implementieren
Start mit einfachem Programm
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Usage: ./permute text\n");
return 1;
}
string text = argv[1];
printf("Input text: %s\n", text);
return 0;
}Fragen:
- Was brauchen wir als nächstes? Wie können wir den Text in Blöcke aufteilen?
- Welche Konstante sollten wir definieren?
- Wie können wir durch den Text in 3er-Schritten iterieren?
Pseudocode: Blockweise iterieren
SIZE = 3
// Einstieg: Erstmal nur Blocks ausgeben
FÜR Position = 0 BIS Textlänge SCHRITTWEITE SIZE:
AUSGABE "Block beginnt bei Position", Position
FÜR j = 0 BIS SIZE:
AUSGABE Text[Position + j]
AUSGABE " | "Erste Erweiterung
#define BLOCK_SIZE 3
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Usage: ./permute text\n");
return 1;
}
printf("Blocks: ");
for (int i = 0; i < strlen(text); i += BLOCK_SIZE)
{
// Jeden Block ausgeben
for (int j = 0; j < BLOCK_SIZE; j++)
{
printf("%c", text[i + j]);
}
printf(" | ");
}
printf("\n");
}Soweit so gut.
Nehmen wir an, wir hätten eine Funktion, die einen Block verarbeitet: VERARBEITE Block.
Dann wäre es gut, wenn wir beim Iterieren etwas hätten, das den aktuellen Block enthält, also so:
// Verbesserung: Mit Array für jeden Block
FÜR Position = 0 BIS Textlänge SCHRITTWEITE SIZE:
ERSTELLE Block[SIZE] // Temporäres Array für aktuellen Block
FÜR j = 0 BIS SIZE:
Block[j] = Text[Position + j]
VERARBEITE Block
AUSGABE BlockDie Block-Extraktion lagern wir am besten in eine Funktion aus.
Phase 3: Block-Extraktion
Aufgabe
Schreiben Sie eine Funktion, die einen einzelnen Block in ein char-Array kopiert:
- Der Block beginnt bei Position
startim Text. - Er soll BLOCK_SIZE Zeichen lang sein.
- Verwenden Sie ein char-Array als Parameter für den erstellten Block.
- Die Funktion gibt nichts zurück.
Besprechung der Lösung
void extract_block(string text, int start, char block[])
{
for (int j = 0; j < BLOCK_SIZE; j++)
{
block[j] = text[start + j];
}
}Diskussionsfragen:
- Warum verwenden wir char[] statt string?
- Was könnte schiefgehen, wenn der Text zu kurz ist?
- Wie können wir das prüfen?
Phase 4: Permutation implementieren
Implementierung
// Einfache Variante: Hart kodiert für Key "201"
EINGABE: Block[BLOCK_SIZE]
ERSTELLE Temp[BLOCK_SIZE] // Warum brauchen wir das?
Temp[2] = Block[0] // 0 geht nach 2
Temp[0] = Block[1] // 1 geht nach 0
Temp[1] = Block[2] // 2 geht nach 1
KOPIERE Temp zurück nach Blockoder in C:
// Erstmal mit festem Key "201" testen
void permute_block(char block[])
{
char temp[BLOCK_SIZE];
// Position 0 geht nach 2
temp[2] = block[0];
// Position 1 geht nach 0
temp[0] = block[1];
// Position 2 geht nach 1
temp[1] = block[2];
// Zurückkopieren
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}Fragen zur Verbesserung:
- Was ist problematisch an diesem Code?
- Wie könnten wir den Key flexibel machen?
- Warum brauchen wir temp[]?
main() für Phase 4 (zum Testen)
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define BLOCK_SIZE 3
void extract_block(string text, int start, char block[])
{
for (int j = 0; j < BLOCK_SIZE; j++)
{
block[j] = text[start + j];
}
}
void permute_block(char block[])
{
char temp[BLOCK_SIZE];
// Position 0 geht nach 2
temp[2] = block[0];
// Position 1 geht nach 0
temp[0] = block[1];
// Position 2 geht nach 1
temp[1] = block[2];
// Zurückkopieren
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Usage: ./permute text\n");
return 1;
}
string text = argv[1];
// Text blockweise verarbeiten
printf("Output: ");
for (int i = 0; i < strlen(text); i += BLOCK_SIZE)
{
char block[BLOCK_SIZE];
extract_block(text, i, block);
permute_block(block);
// Block ausgeben
for (int j = 0; j < BLOCK_SIZE; j++)
{
printf("%c", block[j]);
}
}
printf("\n");
return 0;
}Test:
./permute HELLOWORLDErwartete Ausgabe: ELHOLWLRDO (jeder 3er-Block wird mit “201” permutiert)
Phase 4.5: Flexibler Key mit String
Problem
Der hartkodierte Key “201” ist unpraktisch. Wir wollen den Key als Parameter übergeben.
Erste Lösung: Key als String
Wir erweitern die Funktion, damit sie einen Key-String entgegennimmt:
void permute_block(char block[], string key_str)Das Problem: Zeichen vs. Zahlen
Der Key ist ein String, also z.B. “201”. Das bedeutet:
key_str[0]ist das Zeichen'2'(nicht die Zahl 2!)key_str[1]ist das Zeichen'0'key_str[2]ist das Zeichen'1'
Wir brauchen aber die Zahlen 2, 0, 1 als Array-Indizes.
Lösung: ASCII-Arithmetik
int pos = key_str[i] - '0';Das Zeichen ‘0’ hat den ASCII-Code 48, ‘1’ hat 49, ‘2’ hat 50, usw.
'2' - '0'= 50 - 48 = 2'0' - '0'= 48 - 48 = 0'1' - '0'= 49 - 48 = 1
Implementation
Pseudocode:
EINGABE: Block[BLOCK_SIZE], KeyString
ERSTELLE Temp[BLOCK_SIZE]
FÜR i = 0 BIS BLOCK_SIZE:
Position = KeyString[i] - '0' // Zeichen zu Zahl konvertieren!
Temp[Position] = Block[i] // Position i geht nach Position
KOPIERE Temp zurück nach BlockIn C:
void permute_block(char block[], string key_str)
{
char temp[BLOCK_SIZE];
for (int i = 0; i < BLOCK_SIZE; i++)
{
int pos = key_str[i] - '0'; // Zeichen zu Zahl konvertieren
temp[pos] = block[i];
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}Verständnisfragen
- Warum subtrahieren wir ‘0’ von key_str[i]?
- Was würde passieren, wenn wir
key_str[i]direkt als Index verwenden? - Welche Werte kann
posannehmen bei einem gültigen Key?
main() für Phase 4.5 (zum Testen)
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define BLOCK_SIZE 3
void extract_block(string text, int start, char block[])
{
for (int j = 0; j < BLOCK_SIZE; j++)
{
block[j] = text[start + j];
}
}
void permute_block(char block[], string key_str)
{
char temp[BLOCK_SIZE];
for (int i = 0; i < BLOCK_SIZE; i++)
{
int pos = key_str[i] - '0';
temp[pos] = block[i];
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}
int main(int argc, string argv[])
{
if (argc != 3)
{
printf("Usage: ./permute key text\n");
return 1;
}
string key_str = argv[1];
string text = argv[2];
// Text blockweise verarbeiten
printf("Output: ");
for (int i = 0; i < strlen(text); i += BLOCK_SIZE)
{
char block[BLOCK_SIZE];
extract_block(text, i, block);
permute_block(block, key_str);
// Block ausgeben
for (int j = 0; j < BLOCK_SIZE; j++)
{
printf("%c", block[j]);
}
}
printf("\n");
return 0;
}Test:
./permute 201 HELLOWORLD
./permute 012 HELLOWORLD
./permute 120 ABCBeobachtung: Noch keine Validierung - ungültige Keys wie “999” oder “abc” führen zu unerwartetem Verhalten!
Phase 5: Key-Validierung
Analyse
- Welche Bedingungen muss ein gültiger Key erfüllen?
- Was passiert bei ungültigen Keys wie ‘011’ oder ‘234’?
Implementation der Validierung
// Nur Grundprüfung
WENN Keylänge ≠ BLOCK_SIZE:
FEHLER "Key muss Länge 3 haben"
FÜR JEDE Ziffer IN Key:
WENN Ziffer < 0 ODER Ziffer ≥ BLOCK_SIZE:
FEHLER "Ungültige Ziffer im Key"Das reicht aber noch nicht.
011 ist keine gültige Permutation, 510 auch nicht.
// Weitere Prüfungen
ERSTELLE Used[BLOCK_SIZE] = {0,0,0} // Zähler für jede Position
FÜR JEDE Ziffer IN Key:
WENN Ziffer < 0 ODER Ziffer ≥ BLOCK_SIZE:
FEHLER "Ungültige Ziffer"
Used[Ziffer]++
FÜR i = 0 BIS BLOCK_SIZE:
WENN Used[i] ≠ 1:
FEHLER "Jede Position muss genau einmal vorkommen"Also in C:
bool is_valid_key(string key_str)
{
// Längenkontrolle
if (strlen(key_str) != BLOCK_SIZE)
{
return false;
}
// Array für Positionszählung
int used[BLOCK_SIZE] = {0};
// Jeden Key-Character prüfen
for (int i = 0; i < BLOCK_SIZE; i++)
{
// Ist es eine gültige Ziffer?
if (key_str[i] < '0' || key_str[i] >= '0' + BLOCK_SIZE)
{
return false;
}
// Position markieren - wieder '0' abziehen!
int pos = key_str[i] - '0';
used[pos]++;
}
// Jede Position genau einmal?
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (used[i] != 1)
{
return false;
}
}
return true;
}Verständnisfragen
- Was bedeutet used[pos]++?
- Wie prüfen wir, ob jede Position genau einmal vorkommt?
- Warum funktioniert
key_str[i] < '0'als Prüfung?
main() für Phase 5 (zum Testen)
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define BLOCK_SIZE 3
void extract_block(string text, int start, char block[])
{
for (int j = 0; j < BLOCK_SIZE; j++)
{
block[j] = text[start + j];
}
}
void permute_block(char block[], string key_str)
{
char temp[BLOCK_SIZE];
for (int i = 0; i < BLOCK_SIZE; i++)
{
int pos = key_str[i] - '0';
temp[pos] = block[i];
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}
bool is_valid_key(string key_str)
{
if (strlen(key_str) != BLOCK_SIZE)
{
return false;
}
int used[BLOCK_SIZE] = {0};
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (key_str[i] < '0' || key_str[i] >= '0' + BLOCK_SIZE)
{
return false;
}
int pos = key_str[i] - '0';
used[pos]++;
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (used[i] != 1)
{
return false;
}
}
return true;
}
int main(int argc, string argv[])
{
if (argc != 3)
{
printf("Usage: ./permute key text\n");
return 1;
}
string key_str = argv[1];
string text = argv[2];
// Key validieren
if (!is_valid_key(key_str))
{
printf("Invalid key\n");
return 1;
}
// Text-Länge prüfen
if (strlen(text) % BLOCK_SIZE != 0)
{
printf("Text length must be multiple of %i\n", BLOCK_SIZE);
return 1;
}
// Text blockweise verarbeiten
printf("Output: ");
for (int i = 0; i < strlen(text); i += BLOCK_SIZE)
{
char block[BLOCK_SIZE];
extract_block(text, i, block);
permute_block(block, key_str);
for (int j = 0; j < BLOCK_SIZE; j++)
{
printf("%c", block[j]);
}
}
printf("\n");
return 0;
}Tests:
./permute 201 HELLOWORLD # Funktioniert
./permute 012 ABCDEFGHI # Funktioniert
./permute 999 ABC # Fehlermeldung: Invalid key
./permute 011 ABC # Fehlermeldung: Invalid key (doppelte Position)
./permute 201 HELL # Fehlermeldung: Text length must be multiple of 3Beobachtung
Fällt etwas auf? Wir ziehen hier schon wieder '0' ab (in is_valid_key()) - genau wie in permute_block() (Phase 4.5). Das wird gleich noch wichtig…
Phase 5.5: Code Smell erkennen und beheben
Das Problem: Code-Duplikation
Schauen wir uns an, wo wir überall '0' abziehen:
In
permute_block()(Phase 4.5):int pos = key_str[i] - '0';In
is_valid_key()(Phase 5):int pos = key_str[i] - '0';Gleich in
main()werden wir das auch noch brauchen:for (int i = 0; i < BLOCK_SIZE; i++) { key[i] = key_str[i] - '0'; // Schon wieder! }
Das ist ein “Code Smell” - ein Hinweis auf schlechtes Design!
Warum ist das problematisch?
- Fehleranfälligkeit: Wenn wir einen Fehler in der Konversion machen, müssen wir ihn an allen Stellen fixen
- Wartbarkeit: Änderungen müssen überall nachgezogen werden
- Verständlichkeit: Der gleiche Code steht mehrfach da
Prinzip: Don’t Repeat Yourself (DRY)
Lösung: parse_key() Funktion
Wir lagern die Konversion in eine eigene Funktion aus:
void parse_key(string key_str, int key[])
{
for (int i = 0; i < BLOCK_SIZE; i++)
{
key[i] = key_str[i] - '0';
}
}Wichtig: Arrays als Parameter
Beobachtung: Die Funktion gibt nichts zurück (void), verändert aber trotzdem das key[] Array!
Grund: Wenn wir ein Array an eine Funktion übergeben, können wir dessen Inhalt verändern - und diese Änderungen sind auch außerhalb der Funktion sichtbar. Das ist anders als bei normalen Variablen!
Beispiel:
int main(void)
{
string key_str = "201";
int key[BLOCK_SIZE];
parse_key(key_str, key); // Funktion füllt das Array
// Jetzt können wir key[] verwenden:
printf("%i %i %i\n", key[0], key[1], key[2]); // Ausgabe: 2 0 1
}Vorteile
Jetzt können wir die anderen Funktionen vereinfachen:
is_valid_key()bekommtint key[]stattstring key_strpermute_block()bekommtint key[]stattstring key_str- Kein
'0'abziehen mehr in diesen Funktionen!
Ablauf in main():
1. Key-String einlesen (z.B. "201")
2. parse_key() aufrufen → int[] erstellen
3. is_valid_key() mit int[] aufrufen
4. permute_block() mit int[] aufrufenPhase 6: Refactoring und Integration
Nach der Einführung von parse_key() können wir jetzt unsere Funktionen vereinfachen.
Schritt 1: is_valid_key() anpassen
Vorher (mit string):
bool is_valid_key(string key_str)
{
if (strlen(key_str) != BLOCK_SIZE)
{
return false;
}
int used[BLOCK_SIZE] = {0};
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (key_str[i] < '0' || key_str[i] >= '0' + BLOCK_SIZE) // Kompliziert!
{
return false;
}
int pos = key_str[i] - '0'; // '0' abziehen!
used[pos]++;
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (used[i] != 1)
{
return false;
}
}
return true;
}Nachher (mit int-Array - viel einfacher!):
bool is_valid_key(int key[])
{
int used[BLOCK_SIZE] = {0};
for (int i = 0; i < BLOCK_SIZE; i++)
{
// Ist es eine gültige Ziffer? Viel einfacher zu lesen!
if (key[i] < 0 || key[i] >= BLOCK_SIZE)
{
return false;
}
// Kein '0' abziehen mehr nötig!
used[key[i]]++;
}
// Jede Position genau einmal?
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (used[i] != 1)
{
return false;
}
}
return true;
}Beachte: Die Längenkontrolle entfällt - die machen wir jetzt in parse_key() oder in main()!
Schritt 2: permute_block() anpassen
Vorher (mit string):
void permute_block(char block[], string key_str)
{
char temp[BLOCK_SIZE];
for (int i = 0; i < BLOCK_SIZE; i++)
{
int pos = key_str[i] - '0'; // '0' abziehen!
temp[pos] = block[i];
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}Nachher (mit int-Array):
void permute_block(char block[], int key[])
{
char temp[BLOCK_SIZE];
for (int i = 0; i < BLOCK_SIZE; i++)
{
temp[key[i]] = block[i]; // Direkt verwenden - kein '0' abziehen!
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}Schritt 3: main() komplett überarbeiten
Jetzt fügen wir alles zusammen. Wichtig ist die Reihenfolge:
int main(int argc, string argv[])
{
if (argc != 3)
{
printf("Usage: ./permute key text\n");
return 1;
}
string key_str = argv[1];
string text = argv[2];
// 1. Prüfen: Ist der Key-String die richtige Länge?
if (strlen(key_str) != BLOCK_SIZE)
{
printf("Key must have length %i\n", BLOCK_SIZE);
return 1;
}
// 2. Key parsen (string → int-Array)
int key[BLOCK_SIZE];
parse_key(key_str, key);
// 3. Validieren (mit int-Array!)
if (!is_valid_key(key))
{
printf("Invalid key\n");
return 1;
}
// 4. Text-Länge prüfen
if (strlen(text) % BLOCK_SIZE != 0)
{
printf("Text length must be multiple of %i\n", BLOCK_SIZE);
return 1;
}
// 5. Text blockweise verarbeiten
printf("Output: ");
for (int i = 0; i < strlen(text); i += BLOCK_SIZE)
{
char block[BLOCK_SIZE];
extract_block(text, i, block);
permute_block(block, key); // Mit int-Array!
// Block ausgeben
for (int j = 0; j < BLOCK_SIZE; j++)
{
printf("%c", block[j]);
}
}
printf("\n");
return 0;
}Komplettes Programm für Phase 6 (zum Testen)
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define BLOCK_SIZE 3
// Block aus Text extrahieren
void extract_block(string text, int start, char block[])
{
for (int j = 0; j < BLOCK_SIZE; j++)
{
block[j] = text[start + j];
}
}
// Key-String in int-Array konvertieren
void parse_key(string key_str, int key[])
{
for (int i = 0; i < BLOCK_SIZE; i++)
{
key[i] = key_str[i] - '0';
}
}
// Key validieren (nimmt jetzt int-Array!)
bool is_valid_key(int key[])
{
int used[BLOCK_SIZE] = {0};
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (key[i] < 0 || key[i] >= BLOCK_SIZE)
{
return false;
}
used[key[i]]++;
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
if (used[i] != 1)
{
return false;
}
}
return true;
}
// Block permutieren (nimmt jetzt int-Array!)
void permute_block(char block[], int key[])
{
char temp[BLOCK_SIZE];
for (int i = 0; i < BLOCK_SIZE; i++)
{
temp[key[i]] = block[i];
}
for (int i = 0; i < BLOCK_SIZE; i++)
{
block[i] = temp[i];
}
}
int main(int argc, string argv[])
{
if (argc != 3)
{
printf("Usage: ./permute key text\n");
return 1;
}
string key_str = argv[1];
string text = argv[2];
// 1. Prüfen: Ist der Key-String die richtige Länge?
if (strlen(key_str) != BLOCK_SIZE)
{
printf("Key must have length %i\n", BLOCK_SIZE);
return 1;
}
// 2. Key parsen (string → int-Array)
int key[BLOCK_SIZE];
parse_key(key_str, key);
// 3. Validieren (mit int-Array!)
if (!is_valid_key(key))
{
printf("Invalid key\n");
return 1;
}
// 4. Text-Länge prüfen
if (strlen(text) % BLOCK_SIZE != 0)
{
printf("Text length must be multiple of %i\n", BLOCK_SIZE);
return 1;
}
// 5. Text blockweise verarbeiten
printf("Output: ");
for (int i = 0; i < strlen(text); i += BLOCK_SIZE)
{
char block[BLOCK_SIZE];
extract_block(text, i, block);
permute_block(block, key);
for (int j = 0; j < BLOCK_SIZE; j++)
{
printf("%c", block[j]);
}
}
printf("\n");
return 0;
}Tests:
./permute 201 HELLOWORLD # Funktioniert
./permute 012 ABCDEFGHI # Funktioniert
./permute 120 ABC # Funktioniert
./permute 999 ABC # Fehlermeldung: Invalid key
./permute 011 ABC # Fehlermeldung: Invalid key
./permute 20 ABC # Fehlermeldung: Key must have length 3
./permute 201 HELL # Fehlermeldung: Text length must be multiple of 3Ideen für weitere Aufgaben zum Üben
- Wie würden wir die Entschlüsselung implementieren?
- Was müsste sich ändern für variable Blocklängen? (erst wenn wir dynamische Speicherverwaltung behandelt haben)
- Wie könnten wir mit Texten umgehen, deren Länge kein Vielfaches von BLOCK_SIZE ist?
Debugging-Tipps
- Nach kleinen Änderungen Kompilieren, um Fehlersuche zu beschleunigen
- Printf nach jedem Schritt für Zwischenergebnisse
- Kleine Testfälle wie “ABC” mit Key “201”
- Systematisches Testen der Randfälle:
- Zu kurzer Text
- Ungültige Keys
- Spezielle Zeichen im Text
Testfälle
Textlänge nicht teilbar durch 3
./permute 201 HELL
Ungültige Keys
./permute 011 HELLOWORLD // Ziffer doppelt
./permute 234 HELLOWORLD // Ziffer zu groß
./permute 21 HELLOWORLD // Key zu kurz`Spezialfälle
./permute 201 "" // Leerer Text
./permute 201 "ABC" // Minimale Länge
./permute 201 "ABCDEF" // Mehrere Blöcke`