Использование minizip для распаковки массива char

У меня есть вектор (который является просто оберткой над массивом символов), который является входом. Pkzip был создан с использованием c # sharpZipLib.

Я сохранил данные в файл, который я пробежал через шаблон почтового индекса hex редактора, который извлек. Вход хороший, он не поврежден. Это все, кроме сжатых данных:

50 4B 03 04 14 00 00 00 08 00 51 B2 8B 4A B3 B6
6C B0 F6 18 00 00 40 07 01 00 07 00 00 00 2D 33
31 2F 31 32 38

<compressed data (6390 bytes)>

50 4B 01 02 14 00 14 00 00 00 08 00 51 B2 8B 4A
B3 B6 6C B0 F6 18 00 00 40 07 01 00 07 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 2D 33
31 2F 31 32 38 50 4B 05 06 00 00 00 00 01 00 01
00 35 00 00 00 1B 19 00 00 00 00

У меня есть другой вектор, который должен быть выходным. Накачанные данные будут иметь около 67-68 Кб, поэтому я знаю, что они помещаются в буфер.

На всю жизнь я не могу заставить минизип раздувать первое и хранить его во втором.

Это то, что я до сих пор:

#include "minizip\zlib.h"
#define ZLIB_WINAPI

std::vector<unsigned char> data;

/*...*/

std::vector<unsigned char> outBuffer(1024 * 1024);

z_stream stream;

stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;

stream.data_type = Z_BINARY;

stream.avail_in = data.size();
stream.avail_out = outBuffer.size();

stream.next_in = &data[0];
stream.next_out = &outBuffer[0];

int ret = inflateInit(&stream);
ret = inflate(&stream, 1);
ret = inflateEnd(&stream);

Я использовал отладчик, чтобы пройти через метод и контролировать ret, inflate возвращаемое значение -3 с сообщением "incorrect header check",

Это pkzip, который является оберткой вокруг zlib, но minizip должна быть библиотека обертка вокруг zlib это должно поддержать pkzipразве не должно быть?
Как мне изменить это, чтобы работать?

1

Решение

Поскольку он начинается с 50 4B 03 04, это файл PKZIP, в соответствии с https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html

Если это zip-файлы, то inflate — неправильная функция. Форматы zlib, gzip и zip все разные. Вы можете читать zip с помощью zlib, если для этого используете правильные функции. Если у вас нет вклада, возможно скачайте и перестройте zlib.

Вот мой старый код, который работает с zip-файлами, используя библиотеку zlib. Я мог бы переместить некоторые заголовки, потому что официальный zlib хранит их в zlib / contrib / minizip.

Аргументами являются имена файлов, поэтому вам придется изменить его или записать свой массив в файл.

// #include <zlib/unzip.h>
#include <zlib/contrib/minizip/unzip.h>

/// return list of filenames in zip archive
std::list<std::string> GetZipFilenames(const char *szZipArchive){
std::list<std::string> results;
unzFile zip = unzOpen(szZipArchive);
if (zip){
unz_global_info info;
int rv = unzGetGlobalInfo(zip, &info);

if (UNZ_OK == unzGoToFirstFile(zip)){
do {
char szFilename[BUFSIZ];
if (UNZ_OK == unzGetCurrentFileInfo(zip, NULL, szFilename, sizeof(szFilename), NULL, 0, NULL, 0))
results.push_back(std::string(szFilename));
} while (UNZ_OK == unzGoToNextFile(zip));
}
}
return results;
}

/// extract the contents of szFilename inside szZipArchive
bool ExtractZipFileContents(const char *szZipArchive, const char *szFilename, std::string &contents){
bool result = false;
unzFile zip = unzOpen(szZipArchive);
if (zip){
if (UNZ_OK == unzLocateFile(zip, szFilename, 0)){
if (UNZ_OK == unzOpenCurrentFile(zip)){
char buffer[BUFSIZ];
size_t bytes;
while (0 < (bytes = unzReadCurrentFile(zip, buffer, sizeof(buffer)))){
contents += std::string(buffer, bytes);
}
unzCloseCurrentFile(zip);
result = (bytes == 0);
}
}
unzClose(zip);
}
return result;
}
2

Другие решения

Если я правильно понимаю вопрос, вы пытаетесь распаковать 6390 байт сжатых данных. Эти сжатые данные являются необработанным потоком deflate, у которого нет заголовка или трейлера zlib. Для этого вам нужно будет использовать inflateInit2(&stream, -15) вместо inflateInit(&stream), -15 запрашивает декомпрессию raw deflate.

1

Zip-Utils

std::vector<unsigned char> inputBuffer;
std::vector<unsigned char> outBuffer(1024 * 1024);

HZIP hz = OpenZip(&inputBuffer[0], inputBuffer.capacity(), 0);
ZIPENTRY ze;
GetZipItem(hz, 0, &ze);
UnzipItem(hz, 0, &outBuffer[0], 1024 * 1024);

outBuffer.resize(ze.unc_size);

Если inputBuffer содержит pkzip файл, этот фрагмент распакует его и сохранит содержимое в outBuffer,

Это все.

0