我有一个压缩文件,它是我希望在Linux中从中提取文件的CAB。由于Linux上没有任何本机CAB提取器,我想我应该试着完成一个
虽然我看过MSZIP文档[0]以及[1]和[2],但即使每个块都是使用改进的DEFLATE压缩器压缩的,我也很难对其进行解压缩。虽然我确实使用了[3]来解压块,但除了第一个块之外,其余的块都有很多缺失的数据[数据完全为空[即0x00填充]
所以我相信我需要手动解决这个问题
不幸的是,我很难理解[2]。所以, 使用以下数据:
ED 9D 79 70 1C C7 75 87 07 E0 4D 88 24 EE 8B 94
04 1E A2 44 51 04 81 05 08 2D 11 4A C2 5E 00 96
...
和以下代码来解析数据:
#!/bin/env python
import os
def to_bin(in_item):
b = ord(chr(in_item))
retval = bin(b).replace("0b", "")
if len(retval) < 8:
lx = 8 - len(retval)
q = "0" * lx
retval = q + retval
return retval
def swapbytes(in_bit_str):
p = in_bit_str[:4]
q = in_bit_str[4:]
return q + p
pth = os.path.join("comp", "test_0.dat")
fp = open(pth, 'rb')
fpd = fp.read(10)
fp.close()
dx = ""
for item in fpd:
cx = to_bin(item)
scx = swapbytes(cx)
dx += scx
print(cx)
print("---> %s" % scx)
print("Final: %s" % dx)
bfinal = dx[0]
btype = dx[1:3]
print("Bfinal: %s" % bfinal)
print("Btype: %s" % btype)
rest = dx[3:]
hlit = rest[:5]
hdist = rest[5:11]
hclen = rest[11:15]
hlitd = int(hlit, 2)
hdistd = int(hdist, 2)
hclend = int(hclen, 2)
print("HLIT: %s [%d]" % (hlit, hlitd))
print("HDIST: %s [%d]" % (hdist, hdistd))
print("HCLEN: %s [%d]" % (hclen, hclend))
我得到以下输出:
$ python tstdcmp.py
11101101
---> 11011110
10011101
---> 11011001
01111001
---> 10010111
01110000
---> 00000111
00011100
---> 11000001
11000111
---> 01111100
01110101
---> 01010111
10000111
---> 01111000
00000111
---> 01110000
11100000
---> 00001110
Final: 1101111011011001100101110000011111000001011111000101011101111000011100000
0001110
Bfinal: 1
Btype: 10
HLIT: 11110 [30]
HDIST: 11011 [27]
HCLEN: 0011 [3]
因此,我从RFC1951[2]中得到的基本概念是,在一个字节中,它是从最高位到最低位的,即7 6 5 4 2 1 0 但对于多个字节,即AB CD,字节交换为CD AB
因此,通过代码,我确定前两个字节ED 9D
实际上应该是9D ED
以位表示:
11011110 11011001
这意味着BFinal==1和BTYPE==10(所以是动态哈夫曼编码)
删除前三位后,我得到:
11110 11011001
因此,从[2]的3.2.7中,我应该有以下几组位的信息:
5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
5 Bits: HDIST, # of Distance codes - 1 (1 - 32)
4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19)
因此,HLIT=11110[30] HDIST=11011[27] HCLEN=0011[3]
但是从上面来看,HLIT应该在257和286之间 HCLEN在4到9之间,但我得到HLIT=30,HCLEN=3
也就是说,3.2.7中的文件:
For even greater compactness, the code length sequences
themselves are compressed using a Huffman code.
这是一个用哈夫曼码进一步压缩的例子吗? 我本希望理解RFC1951[2],但它令人非常困惑
我看过一些关于DEFLATE压缩的Youtube视频;但它们主要显示的是算法,而不是字节如何打包到文件中
非常感谢您的帮助
谢谢
[1]How to decompress MSZIP files with c#?
HLIT
等值将完全按照RFC中的说明进行存储。前五位是文字/长度代码的数量减去257。所以你取五位的值,它给出一个0..31的数字,再加上257。这个数字的范围是257到288。允许的范围实际上是257..286,如同一行所述,因此五位的最后两个可能值30和31不应出现在有效的deflate流中李>inflate
函数的文档李>inflateResetKeep()
函数重新启动充气过程,同时保留上一次充气操作中的字典李>以下是使用infgen对您提供的deflate流的初始字节进行解码,以供参考:
相关问题 更多 >
编程相关推荐