首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >恢复bzip2文件

恢复bzip2文件
EN

Code Golf用户
提问于 2014-07-16 05:58:12
回答 1查看 523关注 0票数 4

流行的.bz2压缩格式用于存储各种东西。更有趣的特性之一是,它由几个独立的可解压缩块组成,允许在文件损坏时恢复部分段。bzip2recover程序包括在bzip2中,允许从bzip2存档中恢复块。在这个挑战中,您将实现bzip2recover的一个简单克隆。

其基本思想是扫描比特流以查找特定的魔术数字,并输出由此魔术号分隔的块以分离文件。继续阅读血淋淋的细节。

从技术上讲,bzip2文件是一个比特流,每组8位都被填充到一个字节中。第一位被放置在字节中最重要的位中,第八位位于字节中最不重要的位中。文件以头"BZh“开头,数字"N”从1到9表示压缩级别(9是最常见的)。然后比特流开始。

比特流被分割成块。每个块编码N*100 of的未压缩文本(例如,用于压缩级别9的900 of文本)。块基本上可以在比特流中的任何地方开始,而不一定从8位边界开始。块以一个幻数开始,它被设置为48位序列0x314159265359 (在ASCII中,"1AY&SY")。例如,字节序列"73 14 15 92 65 35 90“包含幻数,在字节内偏移4位。

您的目标是在stdin上获取一个bzip2文件,并将每个检测到的BZip2块输出到一个单独的可解压文件中。具体来说,您的程序执行以下操作:

  • 读取和跳过bzip2头("BZh“+ N)
  • 扫描比特流以获得神奇的序列
  • 将两个连续魔术序列之间的比特流复制到一个新文件中,其中包含一个新的BZip2头和块头。请注意,这可能需要重新对齐比特流,使其从字节边界开始,并填充最后一个字节。

您不必关心对块的解析,您可以假设神奇的序列总是启动块(也就是说,它不在块的中间)。

如何命名输出文件取决于您。唯一的要求是,它们在某种程度上是明显顺序的(因此,例如"a b c . z aa ab“或"1 2 3 4 5.9 10 11 12”都是可以接受的)。

对于测试用例,您可以使用IPSC 2014问题解决竞赛中的这个文件。该文件是一个具有四个块的bzip2文件。该文件作为一个整体实际上解压缩为另一个具有162个完整块的bzip2文件。因此,您可以使用这些块计数来验证您的解决方案是否获得了所有的块。(请注意,该文件实际上进一步解压缩为更多的bzip2文件,但您可能不想一路解压缩它)。

这是代码高尔夫,有点扭曲:你的分数是bz2压缩版本的源代码中的字节数。(我知道这可能会使提交的内容更大,但这是规则!)由于bzip2压缩器的性能可能不同,所以提供一个base64 64编码的压缩文件版本来证明它的大小。(因此,您可以通过优化bzip2的程序来获得更好的成绩,尽管我不一定希望有人这样做)。适用标准漏洞。

EN

回答 1

Code Golf用户

发布于 2014-07-27 18:59:16

Python3-375(534个字符)

它可以使用d2.in在大约10秒内处理示例文件Pypy3。使用CPython 3,它将花费60秒。

有趣和奇怪的是,一些古老的高尔夫球技巧会使比分更糟!例如,用<space>+<space>代替+将把分数从375提高到384;用R代替所有range也会将分数提高到384。

Golfed

代码语言:javascript
复制
import sys
from collections import deque
def T(B):
 for i in range(0,len(B),8):
  x=0
  for j in range(min(8,len(B)-i)): x |= B[i + j] << (7-j)
  yield x
V=sys.argv
C=F=0
B=bytearray()
I=open(V[1],'rb')
H=I.read(4)
P=deque([(x>>(7-j)) & 1 for x in b'1AY&SY' for j in range(8)])
Q=deque([0]*48)
for x in I.read():
 for j in range(8):
  b=(x>>(7-j)) & 1
  B.append(b)
  Q.popleft()
  Q.append(b)
  if Q!=P: continue
  C+=1
  M,B=B[:-48],B[-48:]
  if F:F.write(bytes(T(M)))
  F=open(V[2] + str(C),'wb')
  F.write(H)
F.write(bytes(T(B)))

Base64

代码语言:javascript
复制
QlpoOTFBWSZTWSoMWQ0AAMLfgAAQYf901zlibSo/t//kMAFaCIaCQANTTTKMnlGg8oeRpPaoNDDAAAAAaAAAAABKaSGmmpplD0jQaAABo00ZNqLfKsdHBd3QgkQ2wY3RfYpMMjPpsyit5Ee6+k6E6ObzlFT2vmgbSKPkni7ZgDkcwTRiLFBmNCuEX/HtOC8KJ+Rg51SkMCiAGXZpXbvaK+DzMLvaEhAM8reCB8HFAsNYfRghS9+i5/IpLrDzGZVhsbVOpQzHIIVZ7zCCgDkcElOMvTuvfw2bruKz2WQuvEg99gDa8T3Kw2GdyMNjEVFVVQj4sU1MaOTUcwQROwt86LfUZAOJE6HqnB60CFO38NJmpifx+trcQ8x5alqRiEGoKC2wJpPkCXpT7fbtFDbLCLQaplK23qMTC5gqGwCghjN3zEtwyKhCz3kixqBr7gya6yPG03rMOGY9hlmV3tS0W/SdC2taUpCoNSEaEnUXckU4UJAqDFkN
票数 3
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/34608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档