【问题标题】:Determine the compressed block size with zlib/minizip使用 zlib/minizip 确定压缩块大小
【发布时间】:2016-08-10 07:12:14
【问题描述】:

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

我需要制作一个带有文件哈希的 XML 文件,因为它是格式所要求的。问题是它需要为每个文件的每 64KB 未压缩数据以及 compressed size of such 64KB block 一个哈希值。 我该怎么做?

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

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


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

【问题讨论】:

    标签: c++ zip zlib


    【解决方案1】:

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

    #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 之外进行签名的我有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-13
      相关资源
      最近更新 更多