解压c语言数字字母,c语言解压http中的gzip文件

这是一篇流水账,记录前两天在解决http中解压gzip数据流程。(写完这篇就可以做其他工作了~~)

目的:c语言解压http的中gzip文件

一、 tcpdump抓包,这条数据包是我试用某app时收到的包,咱们先是用wireshark解析。

f4580c224bf1dc93ab1c480880115e6d.png

图上的标号解释下:

1.Content-Encoding: gzip\r\n   指明数据包是gzip;

2.Okhttp走的并不是原生的http请求,因此他在header里面并没有真正的User-Agent,而是“okhttp/版本号”这样的字符串,因为后台需要统计信息,要求传入正确的User-Agent;(这段网上复制的)

3.gzip数据包有1376字节;

4.gzip压缩的数据,可以看到数据包的前6字节1f8b08,1F0B代表gzip格式,08代码deflate算法;

5.因为有gzip标识,所以wireshark自动解压出来了gzip数据,如果用printf打印,是乱码,必须解压;

6.同5;

7.这里的字段是我们最终要找的字段,我给打码了,是这个app的账号;

8.gzip有1376字节,解压后的大小为4093字节。

二、c语言找到gzip数据包起始位置

1.从http字段找到“Content-Encoding: gzip”,可以在这里判断http数据是否用gzip压缩过,以 \r\n\r\n结尾的表示http报文结束(gzip是压缩过的数据,紧跟在http结束标志后面)

2.紧跟着的一组ascll码是gzip数据包的大小,xxxxxx\r\n ,这里的\r\n为gzip长度结束;

3.接下来的位置是gzip数据包的起始位置;

好了,到现在gzip起始位置与gzip数据包长度都找到了,一切都好说咯~

//贴一段功能函数,ascll码转十进制

int chrtodec(char chr)

{

int value=0;

//先全部将小写转换为大写

if((chr>='a')&&(chr<='z'))

chr=chr-32;

//将字符转化成相应的数字

if((chr>='0')&&(chr<='9'))

value=chr-48;

else if((chr>='A')&&(chr<='Z'))

value=chr-65+10;

return value;

}

三、gzip解压

1.方式一,gzip数据写在文件里,在命令行解压这个文件,虽说可以成功,但比较笨拙的赶脚,不推荐。

2.方式二,调用zlib库,在内存里解压,这段代码不是我写的,从某一位网友那里copy过来的,很好用。(详见本文最后几个链接)

/* Gzip uncompress*/

/* 注意:gzip和zip解压大致相同,但是他们的头数据大小不一样,这个得注意,用inflateInit2(&d_stream,47)*/

int

vidpeek_uncompressGzip(unsigned char* pSrc, unsigned int srcSize,char**pOutDest, unsigned int* pOutBufSize)

{

#define OK 0

#define ERR -1

int ret = OK;

char* pBuf = pSrc+ (srcSize - 1);

unsigned int len =*pBuf;

int uncompressResult;

z_stream d_stream;

int i = 0;

printf("#############pSrc 0x%x 0x%x 0x%x 0x%x", pSrc[0], pSrc[1], pSrc[2], pSrc[3]);

//check gz file,rfc1952 P6

if((*pSrc !=0x1f)||(*(pSrc+1) != 0x8b))

{

printf("\nuncompressGzip non Gzip\n");

return ERR;

}

for(i = 0; i < 3; i++)

{

pBuf--;

len <<= 8;

len += *pBuf;

}

//fortest

if((len== 0) || (len > 1000000))

{

printf("\nuncompressGzip,error gzip!\n");

return ERR;

}

//gzipdecompression start!!!

d_stream.zalloc =Z_NULL;

d_stream.zfree =Z_NULL;

d_stream.opaque = Z_NULL;

d_stream.next_in =Z_NULL;

d_stream.avail_in= 0;

uncompressResult =inflateInit2(&d_stream,47);

if(uncompressResult!=Z_OK)

{

printf("\ninflateInit2 error:%d\n",uncompressResult);

return uncompressResult;

}

d_stream.next_in=pSrc;

d_stream.avail_in=srcSize;

d_stream.next_out=(char *)*pOutDest;

d_stream.avail_out=len;

uncompressResult =inflate(&d_stream,Z_NO_FLUSH);

switch(uncompressResult)

{

case Z_NEED_DICT:

uncompressResult = Z_DATA_ERROR;

case Z_DATA_ERROR:

case Z_MEM_ERROR:

(void)inflateEnd(&d_stream);

return uncompressResult;

}

//printf("outlen= %d, total_in= %d, total_out= %d, avail_out= %d@@@@@@@@@@@\n",len, d_stream.total_in, d_stream.total_out, d_stream.avail_out);

inflateEnd(&d_stream);

*pOutBufSize = len-2;

return ret;

}

四、解析解压成功的数据

根据解压成功数据,找到目标字段,比如 "p":"  ,注意c语言的双引号前面要加"\"。

结果:成功找到gzip中的app账户字段!

参考链接

https://blog.csdn.net/fcryuuhou/article/details/12951279

https://blog.csdn.net/qinggebuyao/article/details/7728520

http://www.openedv.com/forum.php?mod=viewthread&tid=231109

好了,溜了~~~

有缘看到的盆友,欢迎提意见啊!

感谢!大家一起技术进步哟~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值