CTF比赛里的OI题??
————————————————————————————
题目描述:
DreamJack 同学最近在学习数据结构,他没事干写了一个压缩软件,准备交给老师当大作业用。
他用哈夫曼树,二叉堆,位图,和字典树实现了软件的压缩部分。
可是他不想写这个软件的解压缩部分,太懒了。
今天 DreamerJack 同学给你发来了一个神秘的 whereIsMyFlag.jzpk 文件,你能破解这个文件吗?
附件描述:
.jzpk 文件,即 Jack ZIP Package 文件,为 DreamerJack 同学开发的新型压缩文件格式。
其文件结构如下定义所述:
头部 \(8Byte\) ,描述该压缩文件数据段所占比特数目 \((Bit)\) 。
剩下的全是数据段,数据段中的数据以比特为最小单位。
数据段:
首先是哈夫曼树字典信息:
for(int i=0;i<256;i++){
占用8Bit空间的整形i_len:指明原文件中值为i的单个字节(8Bit)被压缩后占用几个比特空间
占用i_len Bit空间的01二进制串:指明原文件中值为i的单个字节被哈夫曼树压缩后的新编码
}
接下来全是用哈夫曼树压缩后的新编码表示的信息.一个比特紧邻一个比特连续不断
举例:
假设我有一哈夫曼树,对于整个文件中每个字节有256种可能的组合,其中只有两种字节在文件中存在:
假设经压缩后长度变化为 \(3Bit\) 。
\(00000001\) ,压缩后为 \(001\)
\(00000000\) ,压缩后为 \(000\)
假设其他的 \(254\) 种字节都没有编码表示
(此处仅举例用)
假设要存储数据 \(10\) ,那么压缩后的数据为 \(001000\) ,长度为 \(6\)
哈夫曼树字典信息为(为查看方便加上空格和换行,实际上空格和换行在二进制文件中并不存在,而且所有 \(0\) 和 \(1\) 都以二进制形式表示)
00000011 000
00000011 001
00000000
00000000
...以此类推 直到 \(256\) 种字节都表示完毕为止(后面还会有 \((256-4)*8\) 个 \(0\) )字典信息长度为 \(2054\)
头部 \(8Byte\) ,指示数据段长度,值为 \(2060\) 的 \(long long\) ,长度为 \(8\)
那么这个文件共 \(8+2054+6\) 个字节。顺序为头部 + 哈夫曼树字典 + 压缩后的信息
备注:所有整型变量均采用小端储存。