Beispielimplementierung der multiplikativen Verschlüsselung

Der Code ist lediglich zum Verstehen des Konzeptes gedacht. Es fehlen verschiedene Überprüfungen, zum Beispiel ob alle Zeichen überhaupt in Z_m abbildbar sind oder ob die Angabe von m oder dem Schlüssel überhaupt gültig sind.

#include <stdio.h>
#include <stdlib.h>
 
/** Länge der Zeichenkette bestimmen **/
int cstrlen(const char* str)
{
    int i=0;
    while (str[i]) i++;
    return i;
}
 
/** euklidischer Algorithmus **/
int ggt(int a, int b)
{
    /** r0=i r1=j r2=... **/
    int i=b, j=a;
    if (a>b)
    {
        i=a;
        j=b;
    }
 
    int rest=1;
    while (rest>0)
    {
        rest=i%j;
        if (rest>1)
        {
            i=j;
            j=rest;
        }
        else if (rest==1)
        {
            return rest;
        }
        else
        {
            return j;
        }
    }
 
    return -1;
}
 
int main ()
{
    int max=0;
    printf ("Wie groß soll das Alphabet sein? (<=26): ");
    scanf("%d", &max);
 
    char str[100]={'\0'};
    printf ("Zu verschlüsselnde Zeichenkette: ");
    scanf ("%s", str);
 
    int* teilerfremd=(int*) malloc (max*sizeof(int));
    int ptr_teiler=0;
 
    /** Schlüssel sind teilerfremd zu max **/
    printf ("mögliche Schlüssel: \n");
    for (int j=2; j<max; j++)
    {
        if (ggt(max, j)==1)
        {
            teilerfremd[ptr_teiler]=j;
            ptr_teiler++;
        }
    }
 
    for (int j=0; j<ptr_teiler; j++)
    {
        printf ("%d ", teilerfremd[j]);
    }
 
    int schluessel=0;
    printf ("\nSchlüssel: ");
    scanf ("%d", &schluessel);
 
    /** Konviertieren der Zeichenkette in eine einfache Zahl im Intervall [0, 26] **/
    for (int j=0; str[j]; j++)
    {
        if (str[j]>='A' && str[j]<='Z')
        {
            str[j]+='a'-'A';
        }
        else if (str[j]<'a' || str[j]>'z')
        {
            int i=1+j;
            for (; str[i]; i++)
            {
                str[i-1]=str[i];
            }
            str[i-1]='\0';
            j--;
        }
    }
 
    printf ("Zeichenkette: %s\n", str);
 
    /** Verschlüsseln durch x=(a*schlüssel) % max **/
    char* crypt=(char*) malloc (cstrlen(str));
    for (int i=0; i<cstrlen(str); i++)
    {
        crypt[i]=(((str[i]-'a')*schluessel) % max)+'a';
    }
 
    printf ("Verschlüsselt: %s\n", crypt);
 
    int invers=0;
    /** schluessel*invers=schluessel % max **/
 
    /** Inverses Element in Zm (Modulorestklasse) = 1+ (i*max) / schluessel,
        wenn der Ausdruck ohne Rest wird. **/
    for (int i=0; i<max; i++)
    {
        if (((1+(i*max)) % schluessel) == 0)
        {
            invers=1+(i*max)/schluessel;
            break;
        }
    }
 
    printf ("invers: %d\n", invers);
 
    /** Entschlüsseln wie Verschlüsseln **/
    char* decrypt=(char*) malloc (cstrlen(crypt));
    for (int i=0; i<cstrlen(crypt); i++)
    {
        decrypt[i]=(((crypt[i]-'a')*invers) % max)+'a';
    }
 
    printf ("Entschlüsselt: %s\n", decrypt);
 
    free(crypt);
    free(decrypt);
}