Codegolf — Восстановить Файл Bzip2

  • Автор темы Aptyp
  • Обновлено
  • 19, Oct 2024
  • #1

Популярный bzip2recover compression format is used to store all sorts of things. One of the more interesting features is that it consists of several independently decompressible blocks, allowing recovery of partial segments if the file is damaged. The bzip2 программа, входящая в комплект bzip2 , allows recovery of blocks from a bzip2recover архив. В этом задании вы создадите простой клон .bz2 .

Основная идея состоит в том, чтобы сканировать битовый поток на предмет определенного магического числа и выводить блоки, ограниченные этим магическим числом, в отдельные файлы. Читайте дальше, чтобы узнать кровавые подробности.


Технически файлы bzip2 представляют собой битовый поток, где каждая группа из 8 бит помещается в байт. Первый бит помещается в самый старший бит байта, а восьмой бит — в самый младший бит байта. Файлы начинаются с заголовка «БЖ», и цифры «Н» от 1 до 9, указывающей уровень сжатия (9 – наиболее распространенный). Затем начинается битовый поток.

Битовый поток разбивается на блоки. Каждый блок кодирует N*100 КБ несжатого текста (например, 900 КБ текста для уровня сжатия 9).

Блоки могут начинаться практически в любом месте битового потока и не обязательно начинаться на 8-битной границе. Блоки начинаются с магического числа, которое представляет собой 48-битную последовательность 0x314159265359 (в ASCII «1AY&SY»). Например, последовательность байтов «73 14 15 92 65 35 90» содержит магическое число, смещенное на 4 бита внутри байта.

  • Ваша цель — взять файл bzip2 на стандартный ввод и вывести каждый обнаруженный блок BZip2 в отдельный распаковываемый файл. В частности, ваша программа делает следующее:
  • Прочтите и пропустите заголовок bzip2 («БЖ» + N)
  • Сканируйте битовый поток на предмет магической последовательности.

Скопируйте битовый поток между двумя последовательными магическими последовательностями в новый файл с новым заголовком BZip2 и заголовком блока. Обратите внимание, что для этого может потребоваться перераспределение битового потока, чтобы он начинался с границы байта, и дополнение последнего байта.

Вам не нужно заботиться о разборе блоков, и вы можете предположить, что магическая последовательность всегда запускает блок (т. е. она не находится в середине блока).


Как вы назовете выходные файлы, зависит от вас. Единственное требование состоит в том, чтобы они были каким-то образом четко последовательными (так, например, «a b c ... z aa ab» или «1 2 3 4 5 .. 9 10 11 12» оба приемлемы). Для тестового примера вы можете использовать этот файл


из конкурса IPSC 2014 по решению задач. Это файл bzip2 с четырьмя блоками. Файл в целом фактически распаковывается в другой файл bzip2, содержащий 162 полных блока. Таким образом, вы можете использовать эти счетчики блоков для проверки того, что ваше решение получает все блоки. (Обратите внимание, что файл на самом деле распаковывается еще больше в файлы bzip2, но вы, вероятно, не захотите распаковывать его полностью). Это гольф с одной особенностью: ваш результат — это количество байтов в версии вашего исходного кода, сжатой с помощью bz2. (Я знаю, что это может привести к отправке материаловбольше

, но таковы правила!). Поскольку компрессоры bzip2 могут различаться по производительности, предоставьте версию сжатого файла в кодировке Base64, чтобы подтвердить его размер. (Поэтому вы, возможно, сможете получить более высокий результат, оптимизировав свою программу для bzip2, хотя я не обязательно ожидаю, что кто-то сделает это). Применяются стандартные лазейки.

Aptyp


Рег
06 Sep, 2006

Тем
70

Постов
190

Баллов
560
  • 26, Oct 2024
  • #2

Python 3 – 375 (534 символа)

Он может обрабатывать файл примера

 
 QlpoOTFBWSZTWSoMWQ0AAMLfgAAQYf901zlibSo/t//kMAFaCIaCQANTTTKMnlGg8oeRpPaoNDDAAAAAaAAAAABKaSGmmpplD0jQaAABo00ZNqLfKsdHBd3QgkQ2wY3RfYpMMjPpsyit5Ee6+k6E6ObzlFT2vmgbSKPkni7ZgDkcwTRiLFBmNCuEX/HtOC8KJ+Rg51SkMCiAGXZpXbvaK+DzMLvaEhAM8reCB8HFAsNYfRghS9+i5/IpLrDzGZVhsbVOpQzHIIVZ7zCCgDkcElOMvTuvfw2bruKz2WQuvEg99gDa8T3Kw2GdyMNjEVFVVQj4sU1MaOTUcwQROwt86LfUZAOJE6HqnB60CFO38NJmpifx+trcQ8x5alqRiEGoKC2wJpPkCXpT7fbtFDbLCLQaplK23qMTC5gqGwCghjN3zEtwyKhCz3kixqBr7gya6yPG03rMOGY9hlmV3tS0W/SdC2taUpCoNSEaEnUXckU4UJAqDFkN
 
in about 10 seconds, using Pypy3. With CPython 3, it will cost 60 seconds.

Интересно и странно, что некоторые старые приемы в гольфе ухудшают счет! Например, замена 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))) by R увеличит счет с 375 до 384; замена всех range by + также увеличит счет до 384.

играл в гольф

<space>+<space>

База64

d2.in
 

Career2


Рег
19 Mar, 2020

Тем
76

Постов
192

Баллов
622
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно