зашифровать файлы с помощью варианта Vernam Cipher на языке C

Я кодирую эту программу, которая позволяет вам шифровать файлы с помощью шифра Vernam на языке C. Я был бы рад, если бы вы проверили мой код и сказали, могу ли я внести в него какие-то улучшения или есть ли какие-либо ошибки.

Запрос, который они мне дали:

Цель состоит в том, чтобы разработать простое приложение, которое позволяет шифровать файлы с помощью варианта шифра Вернама, называемого здесь bvernan. Предлагаемый алгоритм использует простое свойство бинарного оператора XOR: (A XOR B) XOR B = A Для заданной последовательности k байтов b0 … bk-1 (называемой ключом) функция кодирования последовательности байтов d0 … dN, функция кодирования / декодирования следует следующей простой процедуре. Последовательность d0 … dN сначала делится на N / k блоков (целочисленное деление), D0, …, D [(N / k) -1] каждый из которых состоит ровно из k байтов (кроме последней последовательности, которая, очевидно, может содержать меньшее количество байтов). Впоследствии каждая последовательность Dj = dj, 0 … dj, k-1 преобразуется в последовательность D’j = d’j, 0 … d’j, k-1 такую, что для каждого i: dj, i = b (j + i) mod k XOR dj, i То есть байт в позиции i блока j помещается в XOR с байтом (j + i) mod k ключа. Выходная последовательность будет тогда получена из сопоставления последовательностей D’0, …, D ‘[(N / k) -1].

Это код:

файл main.c

#include "encode.h"

int main (int argc ,char** argv){
    if(argc!=4){
        printf("Usage: bvernan keyfile inputfile outputfile n");
        return 1;
    }
    
    Key_t* key=openKey(argv[1]);
    
    Register_t* file=openFile(argv[2],argv[3],key->lenght);
    encode(file,key);
    closeRegister(file);
    freeKey(key);
    printf("Success!n");
}

файл encode.c

#include "encode.h"

int encode (Register_t* file, Key_t* key ){
    while(readF(file)>0){
        encodeDivision(file->buffer,file->bufferLenght,key);
        writeF(file);
    }
}
void encodeDivision (unsigned char* block,long lenght,Key_t*key){
    for(int i=0;i<lenght;i++){
        block[i]=block[i]^key->buffer[i];
    }
}

файл encode.h

#include "key.h"
#include "register.h"

int encode (Register_t* file, Key_t* key );
void encodeDivision (unsigned char* block,long lenght,Key_t*key);

файл key.c

#include "key.h"
#include <stdio.h>  
#include <stdlib.h>


long keySize (FILE* file){
    fseek (file,0,SEEK_END);
    long size=ftell(file);
    rewind (file);
    return size;
}
Key_t* openKey(char* path){
    Key_t* kFile= malloc (sizeof(Key_t));
    FILE*file= fopen(path,"rb");
    kFile->lenght=keySize(file);
    kFile->buffer= malloc(kFile->lenght);
    fread(kFile->buffer,1,kFile->lenght,file);
    fclose(file);
    return kFile;
}
void freeKey (Key_t* key ){
free (key->buffer);
free (key);
}

файл key.h

typedef struct Key
{
    unsigned char* buffer; 
    long lenght;
} Key_t; 

Key_t* openKey(char* path);
void freeKey (Key_t*);   


файл register.c

#include <stdio.h>
#include <stdlib.h>
#include "register.h"

Register_t* openFile (char* inPath,char* outPath,long bufferLenght){
    Register_t* file = malloc (sizeof(Register_t));
    file->buffer= malloc(bufferLenght);
    file->bufferLenght=bufferLenght;
    file->fdIn= fopen(inPath,"rb");
    file->fdOut= fopen(outPath,"wb");
    if(file->fdOut==NULL || file->fdIn==NULL){
        return NULL;
    }
        return file;
}
int readF (Register_t* file){
    int readbyte = fread(file->buffer,1,file->bufferLenght,file->fdIn);
    file->bufferLenght=readbyte;
    return readbyte;
}
int writeF (Register_t* file){
    int writebyte = fwrite(file->buffer,1,file->bufferLenght,file->fdOut);
    return writebyte;
}
void closeRegister (Register_t* file){
    free(file->buffer);
    fclose(file->fdIn);
    fclose(file->fdOut);
    free(file);
}

файл register.h

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

typedef struct Register
{
    unsigned char *buffer;
    FILE *fdIn;
    FILE *fdOut;
    long bufferLenght;
} Register_t;

Register_t *openFile(char *inPath, char *outPath, long bufferLenght);
int readF(Register_t *);
int writeF(Register_t *);
void closeRegister(Register_t *);

файл Makefile

all: bvernan    

bvernan: encode.o key.o main.o register.o
    gcc -o bvernan $^

%.o: %.c
    gcc -c $<

clean:
    rm *.o bvernan

1 ответ
1

Могу ли я внести в него какие-то улучшения или есть какие-либо ошибки.

Отсутствие проверки ошибок

fopen(), malloc(), ftell(), fread(), (все функции ввода-вывода) и т. д. заслуживают того, чтобы их возвращаемые значения проверялись на наличие ошибок.

В частности, когда файл может не открываться или не удается выделить память, обрабатывайте такие случаи, чтобы не забыть о другом. например: не забудьте fclose(), или же fclose() дважды, когда не удалось выделить память.

Изящно обрабатывать ошибки и при этом поддерживать хороший поток кода — непростая задача.

Отсутствие комментариев

некоторый комментарии могут помочь, особенно в файлах .h. Иногда файлы заголовков — это все, что пользователь видит (или хочет видеть).

.h файлы

Отсутствует код охранников.

Уменьшите разброс пространства имен. Рекомендовать общий префикс для объектов в файле .h

Типы

long ОК для большинства размеров файлов. size_t лучше для определения размера и индексации массива.

long lenght ... for(int i=0;i<lenght;i++) -> i а также length должен быть одного типа: size_t.

Стиль

Используйте автоматический форматировщик, чтобы улучшить внешний вид кода с меньшими затратами времени.

Толерантный свободный

Обратите внимание, что free(NULL) хорошо определено. Сделайте то же самое для freeKey(NULL);

Написание

lenght -> length.

Пространства

Стиль очень плотный, левый = правый = правый. Некоторые пробелы помогут.

// block[i]=block[i]^key->buffer[i];
block[i] = block[i] ^ key->buffer[i];

Включить заказ

Для xxx.c я рекомендую сначала включить xxx.h, чтобы проверить его автономность.

// file register.c

#include "register.h"  // Put first
#include <stdio.h>
#include <stdlib.h>

Непонятно почему register.h имеет #include <stdlib.h>. Излишний #include файлы в файле .c имеют свое место и не вызывают особого беспокойства. (Некоторые среды программирования предлагают проверку.)

.h файл должен использовать минимальный набор.

Именование

Подумайте об использовании того же дело и заказывать имена key.c, Key_t -> key.c, key_t. keySize(), openKey() -> keySize(), keyOpen().

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *