本文介绍了Qt quncompress gzip数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我绊倒了一个问题,找不到一个解决方案。



所以我想做的是在qt中解压缩数据,使用qUncompress(QByteArray),从www以gzip格式发送。我使用wireshark确定这是有效的gzip流,也测试与zip / rar和两个可以解压缩。



代码到目前为止,是这样:

  static const char dat [40] = {
0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00, 0x00,0x03,0xaa,0x2e,0x2e,0x49,0x2c,0x29,
0x2d,0xb6,0x4a,0x4b,0xcc,0x29,0x4e,0xad,0x05,0x00,0x00,0x00,0xff,0xff,0x03, 0x00,
0x2a,0x63,0x18,0xc5,0x0e,0x00,0x00,0x00
};
//此数据包含字符串:{status:false},格式为gzip
QByteArray data;
data.append(dat,sizeof(dat));

unsigned int size = 14; //预期的未压缩大小,重建它BigEndianes

//预期未压缩大小,dat中最后4个字节0x0e = 14
QByteArray dataPlusSize;

dataPlusSize.append((unsigned int)((size>> 24)& 0xFF));
dataPlusSize.append((unsigned int)((size>> 16)& 0xFF));
dataPlusSize.append((unsigned int)((size>> 8)& 0xFF));
dataPlusSize.append((unsigned int)((size>> 0)& 0xFF));

QByteArray uncomp = qUncompress(dataPlusSize);
qDebug()<< uncomp;

解压缩失败与:qUncompress:Z_DATA_ERROR:输入数据已损坏。



AFAIK gzip由10字节头,DEFLATE peyload,12字节尾(8字节CRC32 + 4字节ISIZE - 未压缩数据大小)组成。
Striping头部和尾部应该留给我DEFLATE数据流,qUncompress产生相同的错误。



我使用PHP压缩的数据字符串进行检查,如下所示:

  $ stringData = gzcompress({status:false},1); 

并且qUncompress解压缩该数据(我没有看到和gzip头虽然ID1 = 0x1f, ID2 = 0x8b)
我用debug调试上面的代码,并且发生错误:

  if #endif 
((BITS(8)<<< 8)+(hold>> 8))%31){//这里是错误,WHY? long unsigned int hold = 35615
strm-> msg =(char *)不正确的头部检查;
state-> mode = BAD;
break;
}

inflate.c第610行。



我知道qUncompress是一个简单的zlib的包装,所以我想它应该处理gzip没有任何问题。任何意见,欢迎。



最好的祝福

解决方案

> dataPlusSize.append(data); 。但是,这不会解决你的问题。问题是,虽然gzip和zlib具有相同的压缩数据格式,但它们的头和尾部是不同的。请参阅: p>

qUncompress 使用zlib uncompress zlib格式,而不是gzip格式。它需要调用 gzXXXX 函数来处理gzip格式。



qUncompress 可以处理PHP的 gzcompress gzcompress 使用ZLIB数据格式压缩给定的字符串。请参阅:



正如CiscoIPPhone所提到的,您需要编写自己的函数来处理gzip数据。


I stumble upon a problem, and can't find a solution.

So what I want to do is uncompress data in qt, using qUncompress(QByteArray), send from www in gzip format. I used wireshark to determine that this is valid gzip stream, also tested with zip/rar and both can uncompress it.

Code so far, is like this:

    static const char dat[40] = {
         0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xaa, 0x2e, 0x2e, 0x49, 0x2c, 0x29,
         0x2d, 0xb6, 0x4a, 0x4b, 0xcc, 0x29, 0x4e, 0xad, 0x05, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00,
         0x2a, 0x63, 0x18, 0xc5, 0x0e, 0x00, 0x00, 0x00
    };
//this data contains string: {status:false}, in gzip format
QByteArray data;
           data.append( dat, sizeof(dat) );

unsigned int size = 14; //expected uncompresed size, reconstruct it BigEndianes

//prepand expected uncompressed size, last 4 byte in dat 0x0e = 14
QByteArray dataPlusSize;

dataPlusSize.append( (unsigned int)((size >> 24) & 0xFF));
dataPlusSize.append( (unsigned int)((size >> 16) & 0xFF));
dataPlusSize.append( (unsigned int)((size >> 8) & 0xFF));
dataPlusSize.append( (unsigned int)((size >> 0) & 0xFF));

QByteArray uncomp = qUncompress( dataPlusSize );
qDebug() << uncomp;

And uncompression fails with: qUncompress: Z_DATA_ERROR: Input data is corrupted.

AFAIK gzip consist of 10 byte header, DEFLATE peyload, 12 byte trailer ( 8 byte CRC32 + 4 byte ISIZE - uncompresed data size ).Striping header and trailer should leave me with DEFLATE data stream, qUncompress yields same error.

I checked with data string compressed in PHP, like this:

$stringData = gzcompress( "{status:false}", 1);

and qUncompress uncompress that data.(I didn't see and gzip header though i.e. ID1 = 0x1f, ID2 = 0x8b )I checked above code with debug, and error occurs at:

        if (
        #endif
            ((BITS(8) << 8) + (hold >> 8)) % 31) { //here is error, WHY? long unsigned int hold = 35615
            strm->msg = (char *)"incorrect header check";
            state->mode = BAD;
            break;
        } 

inflate.c line 610.

I know that qUncompress is simply a wrapper to zlib, so I suppose it should handle gzip without any problem. Any comments are more then welcome.

Best regards

解决方案

You also forgot dataPlusSize.append(data);. However, that won't solve your problem. The problem is that while gzip and zlib have the same compressed data format, their headers and trailers are different. See: http://www.zlib.net/zlib_faq.html#faq18

qUncompress uses the zlib uncompress, so it can only handle the zlib format, not the gzip format. It would need to call the gzXXXX functions to handle the gzip format.

The reason that qUncompress can handle output from PHP's gzcompress is that gzcompress compresses the given string using the ZLIB data format. See: http://php.net/manual/en/function.gzcompress.php

As CiscoIPPhone mentioned, you'll need to write your own to functions to handle gzip data.

这篇关于Qt quncompress gzip数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 02:08