LogNotes

2025-05-13 23:17:04
#xor.c #buff

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

#define BUFFER_SIZE (4 * 1024) // 4 КБ буфер
#define MAX_KEY_SIZE (1024 * 1024) // Максимальный размер ключа: 1 МБ

void xorFile(const char *input_filename, const char *key_filename, const char *output_filename) {
    FILE *input_file = fopen(input_filename, "rb");
    if (!input_file) {
        fprintf(stderr, "Error opening input file: %s\n", input_filename);
        exit(1);
    }

    FILE *key_file = fopen(key_filename, "rb");
    if (!key_file) {
        fprintf(stderr, "Error opening key file: %s\n", key_filename);
        fclose(input_file);
        exit(1);
    }

    FILE *output_file = fopen(output_filename, "wb");
    if (!output_file) {
        fprintf(stderr, "Error opening output file: %s\n", output_filename);
        fclose(input_file);
        fclose(key_file);
        exit(1);
    }

    // Определяем размер ключа
    fseek(key_file, 0, SEEK_END);
    size_t key_length = ftell(key_file);
    fseek(key_file, 0, SEEK_SET);

    if (key_length == 0) {
        fprintf(stderr, "Error: Key file is empty\n");
        fclose(input_file);
        fclose(key_file);
        fclose(output_file);
        exit(1);
    }
    if (key_length > MAX_KEY_SIZE) {
        fprintf(stderr, "Error: Key file is too large\n");
        fclose(input_file);
        fclose(key_file);
        fclose(output_file);
        exit(1);
    }

    unsigned char *key = malloc(key_length);
    if (!key) {
        perror("Memory allocation failed");
        fclose(input_file);
        fclose(key_file);
        fclose(output_file);
        exit(1);
    }

    if (fread(key, 1, key_length, key_file) != key_length) {
        fprintf(stderr, "Error reading key file: %s\n", key_filename);
        free(key);
        fclose(input_file);
        fclose(key_file);
        fclose(output_file);
        exit(1);
    }

    // Буфер для чтения/записи
    unsigned char *buffer = malloc(BUFFER_SIZE);
    if (!buffer) {
        perror("Memory allocation for buffer failed");
        free(key);
        fclose(input_file);
        fclose(key_file);
        fclose(output_file);
        exit(1);
    }

    size_t key_index = 0;
    size_t bytes_read;

    // Чтение и обработка входного файла блоками
    while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, input_file)) > 0) {
        // Выполняем XOR для каждого байта в буфере
        for (size_t i = 0; i < bytes_read; i++) {
            buffer[i] ^= key[key_index];
            key_index = (key_index + 1) % key_length;
        }

        // Записываем обработанный буфер в выходной файл
        if (fwrite(buffer, 1, bytes_read, output_file) != bytes_read) {
            fprintf(stderr, "Error writing to output file: %s\n", output_filename);
            free(buffer);
            free(key);
            fclose(input_file);
            fclose(key_file);
            fclose(output_file);
            exit(1);
        }
    }

    if (ferror(input_file)) {
        fprintf(stderr, "Error reading input file: %s\n", input_filename);
        free(buffer);
        free(key);
        fclose(input_file);
        fclose(key_file);
        fclose(output_file);
        exit(1);
    }

    free(buffer);
    free(key);
    fclose(input_file);
    fclose(key_file);
    fclose(output_file);

    printf("Successfully wrote to %s\n", output_filename);
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        fprintf(stderr, "Usage: %s <input file> <key file> <output file>\n", argv[0]);
        return 1;
    }
    if (strcmp(argv[1], argv[3]) == 0) {
        fprintf(stderr, "Error: Input and output files cannot be the same\n");
        return 1;
    }

    xorFile(argv[1], argv[2], argv[3]);
    return 0;
}
← Previous Next →
Back to list