Block-Cipher (Lösung)
Code aus der Vorlesung
Den folgenden Code haben wir zusammen erarbeitet.
Wichtig: Nützlicher als das fertige Programm ist das Durcharbeiten der in der Vorlesung gezeigten Schritt-für-Schritt-Vorgehensweise. Der Code dort ist zwar nicht mit dem Code aus der Vorlesung identisch; er wird jedoch Schritt für Schritt entwickelt und ist ebenfalls eine vollständige Lösung.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define SIZE 3
void extract_block(string text, int start, char block[]);
void print_block(char block[]);
void permute_block(char block[], char key[]);
int validate_input(string text, char key[]);
// ./permue KEY PLAINTEXT
int main(int argc, string argv[])
{
if (argc != 3)
{
printf("Usage: ./permute needs two parameters!\n");
return 1;
}
string key = argv[1];
string text = argv[2];
if(validate_input(text, key) != 0)
{
return 1;
}
printf("Key: %s - Input: %s\n", key, text);
// Annahme: Länge muss Vielfaches von SIZE
for (int i = 0, len = strlen(text); i < len; i += SIZE)
{
char block[SIZE];
extract_block(text, i, block);
// block[0] = H, block[1] = E, block[2] = L
permute_block(block, key);
print_block(block);
}
}
void permute_block(char block[], char key[])
{
int key_int[SIZE];
for (int i = 0; i < SIZE; i++)
{
key_int[i] = key[i] - '0';
}
char temp[SIZE];
for (int i = 0; i < SIZE; i++)
{
temp[ key_int[i] ] = block[ i ];
}
for (int i = 0; i < SIZE; i++)
{
block[i] = temp[i];
}
}
void print_block(char block[])
{
printf("%c", block[0]);
printf("%c", block[1]);
printf("%c", block[2]);
printf(" - ");
}
void extract_block(string text, int start, char block[])
{
for (int j = 0; j < SIZE ; j++)
{
block[j] = text[start + j];
}
}
int validate_input(string text, char key[])
{
if (strlen(text) % SIZE != 0)
{
printf("String muss ein Vielfaches von %i sein!\n", SIZE);
return 1;
}
if (strlen(key) % SIZE != 0)
{
printf("Key muss die Länge %i haben!\n", SIZE);
return 1;
}
for (int i = 0; i < SIZE; i++)
{
// SIZE ist ja 3, wir wollen aber max. Keys mit 2 zulassen, daher - 1
if (key[i] < '0' || key[i] > ('0' + SIZE - 1) )
{
printf("Key muss aus Ziffern zwischen 0 und %i bestehen!\n", SIZE - 1);
return 1;
}
}
// wie oft kommt die Ziffer am Index vor, d.h. used[0] = 5 heißt: die 0 kam 5x vor
int used[SIZE] = { 0 }; // belegt alles mit 0
for (int i = 0; i < SIZE; i++)
{
int key_as_int = key[i] - '0'; // z.B. 2 wenn '2'
used[key_as_int]++;
}
for (int i = 0; i < SIZE; i++)
{
if (used[i] != 1)
{
printf("Die Ziffer %i kommt nicht genau 1x vor!\n", i);
return 1;
}
}
return 0;
}