Реализация шифра цезаря на C

August 21, 2018 19:18

Шифр Цезаря - это шифр подстановки. Что это значит? Все очень просто! Каждый символ в тексте заменяет на символ со сдвигом (сдвиг постоянен для алфавита, может быть влево или вправо). Например, при шифровании со сдвигом вправо на 4, Б будет заменена на Е, В - на Ё, Г - Ж и т.д.

/* 
    Пример реализации алгоритма (шифра) цезаря
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ALPHA_LEN 26


void generate_alpha(char *alpha, const char *key, int k)
{
    for (int i = 0; i < strlen(key); ++i)
        alpha[i + k] = key[i];

    for (int i = k + strlen(key), j = 0; j < ALPHA_LEN; j++)
    {
        if (!strchr(key, 'a' + j))
            alpha[i++ % ALPHA_LEN] = 'a' + j;
    }
}

void encrypt(char *data, const char *key, int k, size_t len)
{
    char alpha[ALPHA_LEN];
    generate_alpha(alpha, key, k);

    for (int i = 0; i < len; ++i)
        data[i] = alpha[data[i] - 'a'];
}

void decrypt(char *data, const char *key, int k, size_t len)
{
    char alpha[ALPHA_LEN];
    generate_alpha(alpha, key, k);

    for (int i = 0; i < len; ++i)
        data[i] = (strchr(alpha, data[i]) - alpha) + 'a';
}

void usage(const char *programm_name)
{
    printf("Usage:\n\t%s %s\n", programm_name, "[-f FILE <key> | -s string <key>] -k <num> [--decode]");
    exit(1);
}

void fatal(const char *what)
{
    fprintf(stderr, "[!]\t Fatal %s\n", what);
    exit(1);
}

int main(int argc, char const *argv[])
{
    if ((argc < 6) || (argc > 7))
        usage(argv[0]);

    char* buffer;
    size_t data_len;
    int k = 0;

    if (!strcmp(argv[4], "-k"))
        k = atoi(argv[5]);

    if (!strcmp(argv[1], "-f"))
    {
        FILE *file = fopen(argv[2], "r");

        if (!file)
            fatal("File not found");

        fseek(file, 0L, SEEK_END);
        data_len = ftell(file);
        rewind(file);
        buffer = malloc(data_len);
        
        if (!fread(buffer, data_len, 1, file))
        {
            fclose(file);
            free(buffer);
            fatal("Can`t read the file :(");
        }
        fclose(file);
    } 
    else if (!strcmp(argv[1], "-s"))
    {
        buffer = strdup(argv[2]);
        data_len = strlen(buffer);
    }
    else
        usage(argv[0]);

    if ((argc == 7) && !strcmp(argv[6], "--decode"))
        decrypt(buffer, argv[3], k, data_len);
    else
        encrypt(buffer, argv[3], k, data_len);

    fprintf(stdout, "%s", buffer);
    free(buffer);

    return 0;
}