Szyfr Afiniczny

Szyfr Afiniczny

Program: napisać w języku ANSI C kod źródłowy programu wykorzystującego szyfr afiniczny z 256-elementowym alfabetem.

Wraz z parametrami wywołania jak w ostatnim przykładzie. Ilość elementów w alfabecie (zakres bajtu: 0-255) daje możliwość wykorzystania programu do szyfrowania plików binarnych.
Zaimplementować w programie wraz z prostym interfejsem (np. opcje wiersza poleceń) szyfrowanie plików binarnych. Sprawdzić poprawne działanie programu wykorzystując np. obrazki, pliki audio, video, ogólnie multimedia.

Film:

Kod programu:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
unsigned n= 256;
unsigned nwd(unsigned, unsigned, int *, int *);
int main(int argc, char *argv[])
{
    int a, b, x, y, koniec = 0;
    unsigned d;

    do{
        int akcja = 0;
        fprintf(stderr, "\nJaka akcje chcesz wykonac:\n1. Szyfrowanie\n2. Deszyfrowanie\n3. Wyjdz z programu\n\n");
        scanf("%d", &akcja);

        if (akcja == 1 || akcja == 2)
        {
            int liczba = 0;
            printf ("Podaj pierwsza liczbe (musi byc ona nieparzysta): ");
            scanf ("%d", &liczba);

            int liczba2 = 0;
            printf ("Podaj druga liczbe: ");
            scanf ("%d", &liczba2);

            a = liczba;
            if (a < 0)
                a = n - (-a) % n;
            else
                a %= n;
            b = liczba2;
            if (b < 0)
                b = n - (-b) % n;
            else
                b %= n;
            d = nwd(a, n, &x, &y);
            if (d != 1) {
                fprintf(stderr, "BLAD: a=%u w kluczu (%u, %u) jest NIEODWRACALNE modulo 256.\n\n", a, a, b);
                return 2;
            }

            if( argc > 1 )
                 listujPliki( argv[ 1 ] );
            else
                 listujPliki( "." );
        }

        if (akcja == 2) {
            int a0 = a, b0 = b;
            a = x > 0 ? x % n : (n - (-x) % n);
            b *= -a;
            b = b >= 0 ? b % n : (n - (-b) % n);
            fprintf(stderr,
            "Przeksztalcenie kluczy (%u, %u) => (%u, %u) mod 256\n Deszyfrowanie kluczem tajnym-odwrotnym: (%u, %u) mod 256:\nPodaj nazwe pliku jaki deszyfowac:\n",
            a0, b0, a, b,
            a, b);
        } else if(akcja == 1)
            fprintf(stderr, "Szyfrowanie kluczem tajnym: (%u, %u) mod 256:\nPodaj nazwe pliku w folderze projektu:\n", a, b);
        else{
            fprintf(stderr, "Wylaczam program!");
        }

        if (akcja == 2) {
            char xa;
            char deszyfowany_plik[100];
            scanf("%100s", deszyfowany_plik);
            FILE *fi_o = fopen(deszyfowany_plik, "rb");
            if (fi_o == NULL)
            {
                printf("Plik do deszyfrowania nie istnieje");
                exit(-1);
            }
            fprintf(stderr, "Podaj nazwe pliku docelowego:\n");
            char plik_docelowy[100];
            scanf("%100s", plik_docelowy);
            FILE *fi = fopen(plik_docelowy, "wb");

            int znak;
            znak = getc( fi_o );

            while( znak != EOF )
            {
                if (0 <= znak && znak <= 255){
                    xa = (0 + (a * (znak - 0) + b) % n);
                    printf( "%c", xa );
                    fprintf(fi, "%c", xa);
                    znak = getc( fi_o );
                }
                else
                    putchar(znak);
            }
            fclose(fi);
            fclose(fi_o);
        }
        else if(akcja == 1){
            char xa;
            char plik_szyfrowany[100];
            scanf("%100s", plik_szyfrowany);
            FILE *fi_o = fopen(plik_szyfrowany, "rb");
            if (fi_o == NULL)
            {
                printf("Plik do zaszyfrowania nie istnieje");
                exit(-1);
            }

            fprintf(stderr, "Podaj nazwe pliku do jakiego zaszyfrowac:\n");
            char plik_docelowy[100];
            scanf("%100s", plik_docelowy);
            FILE *fi = fopen(plik_docelowy, "wb");

            int znak;
            znak = getc( fi_o );

            while( znak != EOF )
            {
                if (0 <= znak && znak <= 255){
                    xa = (0 + (a * (znak - 0) + b) % n);
                    printf( "%c", xa );
                    fprintf(fi, "%c", xa);
                    znak = getc( fi_o );
                }
                else
                    putchar(znak);
            }
            fclose(fi);
            fclose(fi_o);
        }
        else
        {
            return 1;
        }
    }while(koniec != 1);
    return 0;
}

unsigned nwd(unsigned a, unsigned b, int *x, int *y)
{
    if (b == 0) {
        *x = 1;
        *y = 0;
    return a;
    } else {
        unsigned d;
        int x1, y1;
        d = nwd(b, a % b, &x1, &y1);
        *x = y1;
        *y = x1 - y1 * (a / b);
        return d;
    }
}

void listujPliki( const char * nazwa_sciezki ) {
    struct dirent * plik;
    DIR * sciezka;

    if(( sciezka = opendir( nazwa_sciezki ) ) ) {
        while(( plik = readdir( sciezka ) ) )
             puts( plik->d_name );
        closedir( sciezka );
    }
    else
         printf( "! Wywołując funkcję opendir(%s) pojawił się błąd otwarcia strumienia dla danej ścieżki, może nie istnieje, lub podano ścieżkę pustą\n", nazwa_sciezki );
}

Słowniczek pojęć:

Jest to szyfr podstawieniowy co oznacza, że jednej literze tekstu jawnego odpowiada jedna litera alfabetu tajnego. Podczas szyfrowania tą metodą kluczem jest para liczb naturalnych (a, b). Wtedy szyfrowana litera l jest wyliczana z funkcji f(l) = al + b mod m. Litera m we wzorze oznacza liczbę liter w alfabecie. W przypadku alfabetu angielskiego m = 26, a w przypadku polskiego m = 32.