Цель
Создайте программу или пару программ, которые совместно разрушают и исправляют файлы с целью предотвращения эффективной работы LZMA2. Процедуры разрушения и исправления должны быть взаимными, чтобы вы могли точно восстановить исходный файл.
Цели
- Собрание сочинений Шекспира на равнине UTF-8 (5 589 891 байт)
- Wikimedia Commons 2013 Изображение года в полном разрешении (1 659 847 байт)
Методы сжатия
- Ubuntu / связанные:
xz -kz5 <infile>
- Окна:
7z.exe a -txz -mx5 <outfile> <infile>
- Другое: Используйте компрессор LZMA2 с уровнем сжатия 5, который сжимает произведения Шекспира до 1570550 байт ± 100 байт.
Подсчет очков; сумма (все в байтах, ls -l
или dir
это):
- Размер программы (ов) (все, что нужно, чтобы обратимо «сломать» / исправить файл)
- Разница в размере (абсолютная) между:
- Сырые собранные произведения Шекспира и ваша модифицированная (несжатая) копия.
- Необработанное фото и ваша измененная (несжатая) копия.
- Разница в размере или 0, в зависимости от того, что больше между:
- Необработанные произведения Шекспира без вашей модифицированной сжатой копии LZMA2.
- Необработанное фото без вашей модифицированной сжатой копии LZMA2.
пример
Плохо выигрывающий, лениво играющий в гольф, но совместимый пример Python 2.x:
import sys
x = 7919 if sys.argv[1] == 'b' else -7919
i = bytearray(open(sys.argv[2], 'rb').read())
for n in range(len(i)):
i[n] = (i[n] + x*n) % 256
o = open(sys.argv[2]+'~', 'wb').write(i)
Бег...
$ python break.py b pg100.txt
$ python break.py f pg100.txt~
$ diff -s pg100.txt pg100.txt~~
Files pg100.txt and pg100.txt~~ are identical
$ python break.py b Glühwendel_brennt_durch.jpg
$ python break.py f Glühwendel_brennt_durch.jpg~
$ diff -s Glühwendel_brennt_durch.jpg Glühwendel_brennt_durch.jpg~~
Files Glühwendel_brennt_durch.jpg and Glühwendel_brennt_durch.jpg~~ are identical
$ xz -kz5 pg100.txt~
$ xz -kz5 Glühwendel_brennt_durch.jpg~
$ ls -ln
-rw-rw-r-- 1 2092 2092 194 May 23 17:37 break.py
-rw-rw-r-- 1 2092 2092 1659874 May 23 16:20 Glühwendel_brennt_durch.jpg
-rw-rw-r-- 1 2092 2092 1659874 May 23 17:39 Glühwendel_brennt_durch.jpg~
-rw-rw-r-- 1 2092 2092 1659874 May 23 17:39 Glühwendel_brennt_durch.jpg~~
-rw-rw-r-- 1 2092 2092 1646556 May 23 17:39 Glühwendel_brennt_durch.jpg~.xz
-rw-rw-r-- 1 2092 2092 5589891 May 23 17:24 pg100.txt
-rw-rw-r-- 1 2092 2092 5589891 May 23 17:39 pg100.txt~
-rw-rw-r-- 1 2092 2092 5589891 May 23 17:39 pg100.txt~~
-rw-rw-r-- 1 2092 2092 3014136 May 23 17:39 pg100.txt~.xz
Гол
- = 194 + абс (5589891 - 5589891) + макс (5589891 - 3014136, 0) + абс (1659874 - 1659874) + макс (1659874 - 1646556, 0)
- = 194 + 0 + 2575755 + 0 + 13318
- 2 589 267 байт. Плохо, но ничего не делая с файлами, получается оценка 4 635 153 байта.
осветление
Это гольф, поэтому вы пытаетесь минимизировать свой счет. Я не уверен, что комментарии указывают на законную дыру в моей оценке или они таковы, потому что я сделал это слишком сложным. В любом случае, вы хотите самый маленький :
- исходный код
- Разница между несжатым измененным файлом и исходным файлом (например, если вы измените его, добавив триллион 0 в конце, ваш счет увеличится на триллион байт)
- Разница между сжатым измененным файлом и исходным файлом (например, чем более несжимаемыми становятся файлы, тем выше ваша оценка). Совершенно несжимаемый файл, который немного увеличивается или не увеличивается вообще, получит 0.
Ответы:
Python, оценка = 120
Делает одноразовый пэд с использованием md5 в режиме счетчика . xors файл с этим. Преимущество заключается в том, что исходные и поврежденные файлы имеют одинаковый размер, а средства для разрушения и исправления - это одна и та же программа.
Сжатые испорченные файлы больше оригиналов.
источник
С 51 = 51 + 0 + 0 + 0 + 0
Под трюками игры в гольф эта программа зацикливается на каждый байт в стандартном вводе и делает эксклюзив - или с бесконечным пэдом из rand (). Я проверял это с помощью rand () в libc OpenBSD 5.5.
Использование:
Чтобы протестировать свою программу, я написал сценарий оболочки test.sh (57 строк), чтобы скомпилировать мою программу и вычислить мой счет.
Заметки о rand () и смещении вправо
Ни один алгоритм сжатия не может сжимать случайные данные. Я могу замаскировать pg100.txt и filament.jpg как случайные данные, если зашифрую их потоковым шифром .
Моя первая идея заключалась в том, чтобы создать зашифрованный текст с использованием исключительного или открытого текста с помощью pad , а затем сохранить шифрованный текст и pad в зашифрованном файле. Это увеличит размер файла и увеличит мою оценку. Очевидный выбор - использовать одну и ту же панель для каждого файла и хранить только зашифрованный текст в зашифрованном файле. Если я просто вызываю rand (), он использует начальное значение по умолчанию 1 и каждый раз делает один и тот же пэд .
OpenBSD 5.5 определяет rand () в stdlib.h и rand.c :
Это линейный конгруэнтный генератор . Большой недостаток в том, что у младших битов короткие периоды. 1-й бит имеет период 2: если вы подбрасываете монету
rand()&1
, то это будут головы, хвосты, головы, хвосты и так далее. N-й бит имеет период 2 n . Есть 31 бит, поэтому вся последовательность имеет период 2 31 .LZMA2 может находить паттерны за короткие промежутки времени и сжимать их. Самый короткий код
~c^rand()
занимает младшие 8 бит и не препятствует сжатию. Правильный сдвиг~c^rand()>>9
помогает, но недостаточно. Я использую~c^rand()>>23
.~c
СЧЕТ: 4227957 = 40 + 0 + 0 + 4019391 + 208526~c^rand()
СЧЕТ: 2474616 = 47 + 0 + 0 + 2463735 + 10834~c^rand()>>9
СЧЕТ: 350717 = 50 + 0 + 0 + 350667 + 0~c^rand()>>23
СЧЕТ: 51 = 51 + 0 + 0 + 0 + 0источник
BrainFuck : 129 (129 + 0 + 0 + 0 + 0) *
random.bf (перевод строки добавлен для удобства чтения)
Для создания
unrandom.bf
нужно поменять последний + во второй строке.Большая часть кода основана на генераторе случайных чисел Даниэля Кристофани, основанном на правилах 30, который позволяет добавлять число к каждому входу и завершать его, когда ввода больше нет.
* Я протестировал байты, которые он обработал до сих пор 212992 (обработано через 12 часов), и оба файла превращаются в сжатый файл 213064. Я думаю, что это может быть сделано к концу недели, чтобы знать наверняка, но я не хочу ждать с публикацией. Я обновлю счет, если это не так, но оставлю решение, так как Правило 30 рулит!
Общая информация: Правило 30 было открыто Стивеном Вольфрамом в 1983 году и, согласно Википедии, оно используется для получения случайных целых чисел в Mathematica.
Компиляция и запуск:
Он использует экспоненциальное время и пространство (итерирует более 32 ячеек на обработанный символ), поэтому ему требуется среда выполнения BrainFuck, которая имеет не менее 178 876 517 ячеек для кодирования файла Shakespear, не обрабатывает non ascii как юникод, имеет более широкие ячейки, чем 8 бит, и использует -1 как eof (для различия между 255 и -1). Я обычно использую переводчиков других людей, но на этот раз я должен быть подключен и продвигать свои собственные:
jitfb компилирует BrainFuck для оптимизированного C и использует Perl Inline :: C для его запуска. Это в комплекте с моим расширенным компилятором BrainFuck . С размером и шириной ячейки в аргументе он выделит около 400 МБ.
источник
CJam, 22 байта
При этом используется генератор с запаздыванием Фибоначчи с рекуррентным соотношением s n = (s n-5 + s n-16 )% 255 (который я выбрал по ошибке, но он все же работает) и тривиальное начальное число для генерации псевдослучайного потока байтов , который затем XOR с входом.
Я протестировал свой код с CJam 0.6 , который был опубликован 1 мая 2014 года.
Как это работает
Гол
источник
PHP, 117 + 0 + 0 + 0 + 0 = 117
Потому что действительно ли вы доверили бы задачу переноса ваших данных до неузнаваемости на любой другой язык?
В то время как все другие решения основаны на «безопасных» конструкциях, таких как «генераторы случайных чисел» или «криптография военного уровня», это решение просто интерпретирует строки как представляющие нечетные числа по модулю 2⋅256 ^ длина и вычисляет их модульные обратные значения .
Демо-версия:
источник
сценарий оболочки, 203
Запуск это:
Не очень переносимый, но может быть сделан за пару байтов. Требуется PGP (возможна также реализация с OpenSSL). Разница ~ 50 байтов между закодированным файлом и оригиналом, вероятно, может быть сохранена.
Подсчет очков:
84 + абс (1659874 - 1659943) + макс (1659874 - 1660084, 0) + абс (5589891 - 5589941) + макс (5589891 - 5590284, 0) = 203
источник
Python, счет = 183 + 7 + 6 + 0 + 0 = 196
Подсчет очков оштрафует вас за то, что вы сделали файл полностью несжимаемым, поскольку тогда сжатый файл становится больше из-за накладных расходов на сжатие. Таким образом, моя программа делает их чуть менее несжимаемыми:
Результат:
источник