为什么此代码只能在4GB以下的文件上正常工作

时间:2018-11-13 19:31:55

标签: c g++

该代码有一个简单的任务,即解密/加密文件并将密码写入新文件,该文件非常适合4GB以下的文件。任何大于4GB(2 ^ 32Bytes)的文件,将产生4GB(2 ^ 32 Bytes)的文件,而不是输入文件的大小。我已经尝试了64Bit扩展(fseeko64,fopen64等),它不会有所作为! 除了我有一个标准程序外,似乎没有这种类型的问题,因为它一次将所有数据写入文件中,而不是成块地写入。我对两个程序使用了相同的功能。如果相关的话,我使用g ++进行了编译

任何帮助将不胜感激。 谢谢

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

int i, a, pwlen, response;
char passwd[64];
__uint8_t pwhash[512];
__uint8_t *message;
int tmp;
char *filename, *sourcefilename;
long int len;
int chunk_length, round, chunkqu, rest;
long int file_length_counter;
int progress;

// functions init
void password();
void encrypt();
void decrypt();

int main(int argc, char **argv) {

    // set chunksize
    chunk_length = 4096*64;
    // check arguments,
    if (!argv[1]) {
        printf("Usage: <inputfile> <mode(x/o)> <sourcefile>\nRead documentation for more info\n");
        return 0;
    }
    if (!argv[2]) {
        printf("No mode specified. Exiting\n");
        return 0;
    }
    if (*argv[2] != 'x' && *argv[2] != 'o') {
        printf("Bad argument. Exiting...\n");
        return 0;
    }
    FILE *fileptr2;
    fileptr2 = fopen(argv[3], "rb");
    if (fileptr2 != NULL) {
        printf("Source file already exists\n");
        return 0;
    }
    sourcefilename = argv[3];

    // open file in read mode to verify its existance
    FILE *fileptr1;
    fileptr1 = fopen(argv[1], "rb");
    if (!fileptr1) {
        printf("File does not exist or is not accessible\n"); 
        return 0;
    }
    filename = argv[1];

    fseek(fileptr1, 0, SEEK_END);
    len = ftell(fileptr1);
    fseek(fileptr1, 0, SEEK_SET);

    // request password and hash it
    password();


    // allocate memory for chunk_length
    message = (__uint8_t*)malloc(chunk_length);
    if (message == NULL) {
        printf("Failed to allocate required memory\n This may be caused by insufficient RAM\n"); 
        return 0;
    }


    // open output file
    fileptr2 = fopen(sourcefilename,"wb");

    // find out chunk quantity and length as well as the leftover "chunk"
    file_length_counter =0;
    round =0;
    while (1) {
        round++;
        file_length_counter += chunk_length;
        if (file_length_counter>=len) {
            rest=chunk_length-(file_length_counter-len);
            chunkqu=round;
            break;
        }
    }


    // main routine
    printf("Progress:\n ");
    for (round=1; round<=chunkqu; round++) {
        progress = round*100/chunkqu;
        printf("\r%d\%%", progress);
        fseek(fileptr1, (round-1)*chunk_length, SEEK_SET);
        fread(message, 1, chunk_length, fileptr1);
        if (*argv[2] == 'x') {encrypt();}
        if (*argv[2] == 'o') {decrypt();}
        if (round==chunkqu) {
            fseek(fileptr2, (round-1)*chunk_length, SEEK_SET);
            fwrite(message, 1, rest, fileptr2);
        }
        else {
            fseek(fileptr2, (round-1)*chunk_length, SEEK_SET);
            fwrite(message, 1, chunk_length, fileptr2);
        }
    }


    // cleanup and exit
    printf("\n");
    fclose(fileptr1);
    fclose(fileptr2);
    free (message);
    return 0;
}

void password() {
    int count, h1, h2, h3, h4, s1, s2, s3, s4, r1, r2;
    count = 0;
    int tmphash[512];

    // request password
    do {
        if (count != 0) {
            printf("Password must exceed 9 characters!\n");
        }
        printf("Enter Passphrase:\n");
        fgets(passwd, 64, stdin);
        count++;
    } while (strlen(passwd) <= 9);
        pwlen = strlen(passwd) -1;

    // initialise variables
    s1 = 0;
    s2 = 0;
    s3 = 0;
    s4 = 0;

    // hash algorithm
    for (i=0; i<pwlen; i++) {
        h1 = passwd[i];
        h2 = passwd[pwlen-i];
        h3 = passwd[pwlen];
        h4 = i<<2;

        for (a=0; a<512; a++) {
            if (i==0) {tmphash[a] = 0;}
            s1 += i&a;
            s1 += h1^h4;
            s2 += a^i;
            s3 += h2>>i%3;
            s4 += h3<<i%5;

            r1 = s1^s2;
            r2 = s3^s4;
            r1 += r1<<i;
            r2 += r2>>5;
            tmphash[a] +=r1&r2;
            tmphash[a] %= 256;
        }
    }
    for (i=0; i<512; i++) {
        pwhash[i] = tmphash[i];
    }
}

void encrypt() {
    for (i=0; i<chunk_length; i++) {
        tmp = message[i];
        tmp += pwhash[i%512];
        tmp %= 256;
        message[i] = tmp;
    }
}

void decrypt() {
    for (i=0; i<chunk_length; i++) {
        tmp = message[i];
        tmp += 256;
        tmp -= pwhash[i%512];
        tmp %= 256;
        message[i] = tmp;
    }
}

0 个答案:

没有答案