流行的.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块输出到一个单独的可解压文件中。具体来说,您的程序执行以下操作:
您不必关心对块的解析,您可以假设神奇的序列总是启动块(也就是说,它不在块的中间)。
如何命名输出文件取决于您。唯一的要求是,它们在某种程度上是明显顺序的(因此,例如"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的程序来获得更好的成绩,尽管我不一定希望有人这样做)。适用标准漏洞。
发布于 2014-07-27 18:59:16
它可以使用d2.in在大约10秒内处理示例文件Pypy3。使用CPython 3,它将花费60秒。
有趣和奇怪的是,一些古老的高尔夫球技巧会使比分更糟!例如,用<space>+<space>代替+将把分数从375提高到384;用R代替所有range也会将分数提高到384。
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)))QlpoOTFBWSZTWSoMWQ0AAMLfgAAQYf901zlibSo/t//kMAFaCIaCQANTTTKMnlGg8oeRpPaoNDDAAAAAaAAAAABKaSGmmpplD0jQaAABo00ZNqLfKsdHBd3QgkQ2wY3RfYpMMjPpsyit5Ee6+k6E6ObzlFT2vmgbSKPkni7ZgDkcwTRiLFBmNCuEX/HtOC8KJ+Rg51SkMCiAGXZpXbvaK+DzMLvaEhAM8reCB8HFAsNYfRghS9+i5/IpLrDzGZVhsbVOpQzHIIVZ7zCCgDkcElOMvTuvfw2bruKz2WQuvEg99gDa8T3Kw2GdyMNjEVFVVQj4sU1MaOTUcwQROwt86LfUZAOJE6HqnB60CFO38NJmpifx+trcQ8x5alqRiEGoKC2wJpPkCXpT7fbtFDbLCLQaplK23qMTC5gqGwCghjN3zEtwyKhCz3kixqBr7gya6yPG03rMOGY9hlmV3tS0W/SdC2taUpCoNSEaEnUXckU4UJAqDFkNhttps://codegolf.stackexchange.com/questions/34608
复制相似问题