代码之家  ›  专栏  ›  技术社区  ›  George Marques

使用zlib/minizip确定压缩块大小

  •  0
  • George Marques  · 技术社区  · 8 年前

    Appx 打包程序(用于Windows应用商店应用)。格式只是包含一些元数据文件的压缩文件。

    我需要制作一个XML文件,其中包含格式所需的文件哈希。问题是,每个文件的每64KB未压缩数据都需要一个哈希 compressed size of such 64KB block . 我该怎么做?

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

    在我看来,我需要要么避免压缩文件(我想避免),要么跳过Minizip的压缩,并使用zlib中的原始数据来压缩文件(对于zlib的API,我不太熟悉,不知道是否可以使每个64KB块都足够单独)。


    TL公司;DR:我如何知道Zip文件中64KB未压缩数据块的压缩大小?

    1 回复  |  直到 8 年前
        1
  •  1
  •   George Marques    8 年前

    最后,我“手动”制作了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之外签名是不可能的。