简体   繁体   中英

C++ : Need help on decrypting a zip file and extracting the contents to memory

I have this requirement to be addressed. User inputs a encrypted zip file (only zip file is encrypted and not contents inside it) which contains a text file. The function should decrypt the zip file using the password or key provided and then unzip the file to memory as an array of chars and return the pointer to the char.

I went through all the suggestions provided including using Minizip, microzip, zlib. But I am still not clear on what is the best fit for my requirement.

So far I have implemented decrypting the zip file using the password and converting the zip file to a string. I am planning to use this string as an input to zip decompresser and extract it to memory. However, I am not sure if my approach is right. If there are better ways to do it, please provide your suggestions along with your recommendations on the library to use in my C++ application.

https://code.google.com/p/microzip/source/browse/src/microzip/Unzipper.cpp?r=c18cac3b6126cfd1a08b3e4543801b21d80da08c

http://www.winimage.com/zLibDll/minizip.html

http://www.example-code.com/vcpp/zip.asp

http://zlib.net/

Many thanks

Please provide your suggestions.

Most, if not all, of the most popular ZIP tools also support command-line usage. So, if I were you I would just run a system command from your C++ program to unzip and decrypt the file using one of these popular ZIP tools. After the textfile has been unzip'ed and decrypted you can load it from the disk into internal memory to further process it from there. A simple solution, but efficient.

Zero'd on using zlib. This link helped me to do that. Thought of sharing this so that it can help someone. In my case I am using that buffer directly instead of writing to a file. http://www.gamedev.net/reference/articles/article2279.asp

#include <zlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <Windows.h>

using namespace std;

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

        char c;
        if ( argc != 2 )
        {
         cout << "Usage program.exe zipfilename" << endl;
         return 0;
        } 

        FILE * FileIn;
        FILE * FileOut;
        unsigned long FileInSize;
        void *RawDataBuff;


        //input and output files
        FileIn = fopen(argv[1], "rb");
        FileOut = fopen("FileOut.zip", "w");

        //get the file size of the input file
        fseek(FileIn, 0, SEEK_END);
        FileInSize = ftell(FileIn);

        //buffers for the raw and compressed data</span>
        RawDataBuff = malloc(FileInSize);
        void *CompDataBuff = NULL;

        //zlib states that the source buffer must be at least 0.1 times larger than the source buffer plus 12 bytes
        //to cope with the overhead of zlib data streams
        uLongf CompBuffSize = (uLongf)(FileInSize + (FileInSize * 0.1) + 12);
        CompDataBuff = malloc((size_t)(CompBuffSize));

        //read in the contents of the file into the source buffer
        fseek(FileIn, 0, SEEK_SET);
        fread(RawDataBuff, FileInSize, 1, FileIn);

        //now compress the data
        uLongf DestBuffSize;
        int returnValue;
        returnValue = compress((Bytef*)CompDataBuff, (uLongf*)&DestBuffSize,
            (const Bytef*)RawDataBuff, (uLongf)FileInSize);

        cout << "Return value " << returnValue;
        //write the compressed data to disk
        fwrite(CompDataBuff, DestBuffSize, 1, FileOut);
        fclose(FileIn);
        fclose(FileOut);

         errno_t err;

       // Open for read (will fail if file "input.gz" does not exist)
       if ((FileIn = fopen("FileOut.zip", "rb")) == NULL) {
            fprintf(stderr, "error: Unable to open file" "\n");
            exit(EXIT_FAILURE);
       }
       else
          printf( "Successfully opened the file\n" );


       cout << "Input file name " << argv[1] << "\n";


       // Open for write (will fail if file "test.txt" does not exist)
       if( (err  = fopen_s( &FileOut, "test.txt", "wb" )) !=0 )
       {
           printf( "The file 'test.txt' was not opened\n" );
           system ("pause");
           exit (1);
       }
       else
          printf( "The file 'test.txt' was opened\n" );

       //get the file size of the input file
       fseek(FileIn, 0, SEEK_END);
       FileInSize = ftell(FileIn);

       //buffers for the raw and uncompressed data
       RawDataBuff = malloc(FileInSize);
       char *UnCompDataBuff = NULL;

       //RawDataBuff = (char*) malloc (sizeof(char)*FileInSize);
       if (RawDataBuff == NULL)
       {
           fputs ("Memory error",stderr);
           exit (2);
       }
       //read in the contents of the file into the source buffer
       fseek(FileIn, 0, SEEK_SET);
       fread(RawDataBuff, FileInSize, 1, FileIn);

       //allocate a buffer big enough to hold the uncompressed data, we can cheat here
       //because we know the file size of the original

       uLongf UnCompSize = 482000; //TODO : Revisit this
       int retValue;
       UnCompDataBuff = (char*) malloc (sizeof(char)*UnCompSize);
       if (UnCompDataBuff == NULL)
       {
           fputs ("Memory error",stderr);
           exit (2);
       }

       //all data we require is ready so compress it into the source buffer, the exact
       //size will be stored in UnCompSize
       retValue = uncompress((Bytef*)UnCompDataBuff, &UnCompSize, (const Bytef*)RawDataBuff, FileInSize);

       cout << "Return value of decompression " << retValue << "\n";
       //write the decompressed data to disk
       fwrite(UnCompDataBuff, UnCompSize, 1, FileOut);

       free(RawDataBuff);
       free(UnCompDataBuff);
       fclose(FileIn);
       fclose(FileOut);

       system("pause");
       exit (0);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM