Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Read binary file chunk by chunk in C

Im new to C, and used to python. But because of current situation in the world my primary computer was destroyed and all I left with is 12 years old laptop. Python would not work really good there.

My goal is to create encryption algorithm. Currently its fairly simple, but I will upgrade it later

How can I read file in chunks and overwrite its data?
here’s my code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

typedef unsigned char byte;

void printa(byte a[]) {
    printf("[");
    for (int i = 0; i < strlen(a); i++) {
        printf("%d", a[i]);
        if (i != strlen(a) - 1) {
            printf(", ");
        };
    };
    printf("]\n");
};

int encrypt(byte data[], byte key[], int keyi) {
    for (int i = 0; i < strlen(data); i++) {
        data[i] += key[keyi];
        keyi = (keyi + 1) * (keyi < strlen(key) - 1); //branchless if (keyi<strlen(key)) {keyi++;} else {keyi=0;};
    };
    return keyi;
};

void encrypt_file(byte filename[], byte key[], int buffer_size) {
    FILE *file;
    byte *buff = calloc(sizeof(byte), buffer_size);
    file = fopen(filename, "rb");
    if (file == NULL) {
        printf("UNABLE TO OPEN FILE\n");
    };
};

int main() {
    encrypt_file("test.txt", "key", 1024);
    return 0;
};

My files will be around 2GB in size, but my laptop ram is 512MB, so I have to use chunking.

>Solution :

To encrypt the file on a block basis, you should use fread and fwrite.

To reset the key index keyi at the end of key, comparing it to strlen(key) - 1 is potentially very inefficient because strlen() iterates on the whole string to locate the null terminator. Just test if key[keyi] is a null byte.

Also don’t worry about branchless code:

  • any good compiler will generate branchless code for a simple test if (key[keyi] == '\0') keyi = 0;
  • branches are not a real issue on modern processors, as long as they can be consistently predicted.

Here is a modified version:

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

typedef unsigned char byte;

int encrypt(byte data[], size_t size, const byte key[], int keyi) {
    for (size_t i = 0; i < size; i++) {
        data[i] ^= key[keyi++];  // involutory encryption (apply twice to decrypt)
        if (key[keyi] == '\0')
            keyi = 0;
    }
    return keyi;
}

int encrypt_file(const char *filename, const char *filename2,
                 const byte key[], size_t buffer_size)
{
    byte *buff = calloc(sizeof(*buff), buffer_size);
    if (buff == NULL) {
        fprintf(stderr, "Cannot allocate memory\n");
        return 1;
    }
    FILE *f1 = fopen(filename, "rb");
    if (f1 == NULL) {
        fprintf(stderr, "Cannot open file %s: %s\n", filename, strerror(errno));
        free(buff);
        return 1;
    }
    FILE *f2 = fopen(filename2, "wb");
    if (f2 == NULL) {
        fprintf(stderr, "Cannot open file %s: %s\n", filename2, strerror(errno));
        fclose(f1);
        free(buff);
        return 1;
    }
    size_t nread;
    int keyi = 0;
    while ((nread = fread(buff, sizeof(*buff), size, f1)) != 0) {
        keyi = encrypt(buff, nread, key, keyi);
        if (fwrite(buff, sizeof(*buff), nread, f2) != nread) {
            fprintf(stderr, "Error writing to file %s: %s\n", filename2, strerror(errno));
            break;
        }
    }
    fclose(f1);
    fclose(f2);
    free(buff);
    return 0;
}

int main() {
    return encrypt_file("test.txt", "test.out", (const byte *)"key", 1024);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading