c++ - 使用 zlib/minizip 确定压缩 block 大小

标签 c++ zip zlib

我正在尝试制作一个跨平台的 Appx打包程序(用于 Windows 商店应用程序)。该格式只是一个带有一些元数据文件的 zip。

我需要制作一个包含文件哈希值的 XML 文件,因为格式需要它。问题是它需要为每个文件的每 64KB 未压缩数据和 compressed size of such 64KB block 计算一个哈希值。 . 我该怎么做?

我正在使用 Minizip library也可以使用 zlib如果需要,直接。

在我看来,我需要避免压缩文件(我想避免)或跳过 Minizip 的压缩并使用 zlib 中的原始内容来压缩文件(我不熟悉 zlib 的 API知道将每个 64KB block 单独制作是否足够可行)。


TL;DR:如何判断 Zip 文件中 64KB 未压缩数据 block 的压缩大小?

最佳答案

我最终“手动”制作了 Zip 文件并单独压缩 block 以计算它们的哈希值。

#include <zlib.h>
#define BLOCK_SIZE 65536

z_stream strm;
// Using init2 to avold the zlib header
deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);

int step = 0.

// len is the length of the whole input file
while (len - step > 0) {
    // Get the size of this block (either 64k or the remaining of the file if less)
    long block_size = (len - step) > BLOCK_SIZE ? BLOCK_SIZE : (len - step);

    // strm_in is the input buffer for the compression
    // skipped the buffer allocation for simplicity
    for (int i = 0; i < block_size; i++) {
        strm_in[i] = input_file_buffer[step + i];
    }

    // Calculate the hash (out of the scope for this question)
    // Store in a particular structure for reference later
    BlockData bd;
    bd.hash = make_block_hash(strm_in, block_size);

    // Update the zlib stream info
    // also skipped the out buffer allocation in this sample
    strm.avail_in = block_size;
    strm.avail_out = out_buffer_size;
    strm.next_in = strm_in;
    strm.next_out = strm_out;

    // Save the total bytes for comparison later
    int total_out_before = strm.total_out; 

    // Compress (assume the out buffer size will be always enough)
    deflate(&strm, Z_FULL_FLUSH); // A Full flush here is needed for the APPX format

    // Save the compressed block in the size
    compressed_file->save_buffer(strm_out, strm.total_out - total_out_before);

    // Save the size of the compressed block
    bd.compressed_size = strm.total_out - total_out_before;

    // Store the block data in a list
    blocks_info->push(bd);

    // Move to the next block
    step += block_size;
}

// End the compressed stream
strm.avail_in = 0;
strm.avail_out = out_buffer_size;
strm.next_in = strm_in;
strm.next_out = strm_out;

int total_out_before = strm.total_out;

// Finish the stream
deflate(&strm, Z_FINISH);

// Save the compression tail to the file
compressed_file->save_buffer(strm_out, strm.total_out - total_out_before);

// Clean up
deflateEnd(&strm);

在经历了所有这些麻烦之后,我找到了一个跨平台的 open source tool打包并签署 Windows 商店应用程序。可能对其他人有帮助,对认为在 Windows 之外进行签名是不可能的我也有帮助。

关于c++ - 使用 zlib/minizip 确定压缩 block 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38806524/

相关文章:

android - Osmdroid - 从 ZIP 打开压缩的图 block ?

python - 排序多个列表的最快方法 - Python

c++ - cppcms 大量未解析的外部符号

c++ - 在 scoped_lock 上进行额外的解锁调用

c++ - 函数返回时面临 'Stack Corruption' 问题

c++ - C++ 前缀递增运算符返回左值这一事实的实际应用

c++ - 宏是否保证没有开销?

java - 在内存中的 zip 中解析 XML

node.js - 如何在 Node.js 中使用 zlib 解压存档?

checksum - 如何解决 Zlib adler32 滚动校验和问题?