Полное техническое руководство: архитектура и формат .nik, движок сжатия и медиакодеки, схема шифрования и квантовая стойкость, защитное усиление, все бенчмарки, а также заметки о сборке, тестировании и дорожной карте.
1 Введение
nikpak — это консольный архиватор для формата .nik. Он был спроектирован вокруг четырёх идей: сжимать лучше, чем существующие инструменты, делать это быстрее, защищать данные современной криптографией и работать без изменений на Windows, macOS и Linux в виде одного небольшого исполняемого файла.
1.1 Цели проектирования
Малый размер. Превзойти RAR 7 на данных, которые люди действительно архивируют в больших объёмах. Аудио, изображения и трекерная музыка определяются по содержимому и сжимаются специализированными кодеками без потерь; всё остальное использует настроенный многопоточный поток Zstandard.
Скорость. Сжатие и извлечение должны ограничиваться диском, а не процессором. На быстром уровне -m2 nikpak архивирует около 200 МБ исходных файлов менее чем за секунду на одном ядре.
Безопасность. Аутентифицированное шифрование с ресурсоёмкой по памяти функцией получения ключа, имена файлов всегда скрыты, подделка всегда обнаруживается, а распаковщик невозможно обманом заставить писать за пределы папки назначения.
Квантовая стойкость. Используется только 256-битная симметричная криптография. В nikpak нигде нет кода RSA, эллиптических кривых или Диффи–Хеллмана, так что алгоритму Шора нечего взламывать.
Переносимость и автоматизация. Один статически слинкованный исполняемый файл, командная строка, совместимая с RAR, предсказуемые коды выхода и -help, документирующий каждую опцию.
1.2 Результаты вкратце
Показатель
Результат
Сравнение с
Фотографии BMP
на 38,8 % меньше
RAR 7.00 -m5
Стереомузыка, 44,1 кГц 16 бит
на 14,6 % меньше (на уровне FLAC -8)
RAR 7.00 -m5
Файлы ProTracker MOD
на 13,3 % меньше
RAR 7.00 -m5
Моноаудио, 8 и 16 бит
на 12,2 % и 15,3 % меньше
RAR 7.00 -m5
197 МБ исходных файлов, максимальный уровень
на 5,5 % меньше (24,4 МБ против 25,9 МБ)
RAR 7.00 -m5 -s -md256m
Те же данные, быстрый уровень -m2
0.9
s
RAR 7.00 -m3 solid: 16,7 с
Шифрование
Argon2id + XChaCha20-Poly1305
RAR5: AES-256-CBC + PBKDF2
Все 10 тестовых наборов, максимальный уровень, против 7-Zip
на 2,4–31,7 % меньше
7-Zip 23.01 -mx9 (раздел 11.7)
Офисные файлы (doc, docx, xls, xlsx, csv, pdf)
на 31,7 % меньше
7-Zip 23.01 -mx9 (раздел 11.7)
Все 10 тестовых наборов, максимальный уровень, против ZIP
на 19,9–60,4 % меньше
ZIP -9, Info-ZIP 3.0 (раздел 11.7)
Исполняемый файл
один файл, без зависимостей; около 9 МБ с окном, 2,3 МБ только командная строка
Windows, macOS, Linux
Как были получены цифры Все измерения получены на одной машине (виртуальная машина Linux x86-64, одно ядро ЦП) с RAR 7.00 и nikpak 1.1.0. Каждый архив снова извлекался и побайтово сравнивался с оригиналом. Полная методика, корпуса и случаи, когда RAR быстрее, описаны в главе 11.
1.3 Для кого это?
nikpak ориентирован на людей, которые архивируют большие объёмы медиа или исходного кода и заботятся о размере и скорости, на разработчиков, которым нужен пригодный для сценариев архиватор с разумными кодами выхода и документированным форматом, и на всех, кому нужно стойкое шифрование без доверия к закрытой реализации. Поскольку командная строка следует соглашениям RAR, внешние оболочки, такие как Total Commander, могут управлять им с минимальной перенастройкой или вообще без неё.
1.4 Как читать это руководство
Главы 2 и 3 описывают, что делает nikpak и как им пользоваться. Главы 4–7 объясняют архитектуру, формат файла, движок сжатия и медиакодеки. Главы 8–10 посвящены шифрованию, квантовой стойкости и укреплению защиты. Глава 11 представляет бенчмарки, глава 12 честно сравнивает nikpak с RAR, а главы 13–15 касаются сборки, тестирования и планов развития.
1.5 Сообщество и контакты
Новости, вопросы, идеи и сообщения об ошибках: с автором nikpak можно связаться через
Те же три ссылки показаны в виде круглых цветных кнопок внизу окна nikpak, под папкой назначения (раздел 3.7), и в конце вывода nikpak -help.
2 Обзор возможностей
2.1 Возможности
Область
Что даёт nikpak
Сжатие
Zstandard (многопоточный, непрерывный) на уровнях от -m1 до -m4, с окном 128 МиБ и поиском длинных совпадений на -m4. На -m5 — много-движковое тело: LZMA2 для двоичных данных и PPMd для текста, выбор пробой; файлы сортируются по типу, как в 7-Zip.
Медиа-интеллект
Определение WAV, AIFF, ProTracker MOD и BMP по содержимому; проба для каждого файла между четырьмя фильтрами (NAC, Shuffle, Shuffle+Delta, MED); автоматический откат к обычному сжатию.
Office, PDF, gzip
Пересжатие Deflate (preflate): потоки Deflate внутри файлов docx, xlsx, pptx, odt, ods, epub, jar, zip, pdf и gz декодируются, сжимаются гораздо лучше и при извлечении восстанавливаются бит в бит (-m4, -m5).
Шифрование
Получение ключа Argon2id (64 МиБ), XChaCha20-Poly1305 в аутентифицированных фрагментах по 64 КиБ; имена, размеры, даты и права шифруются.
Пароли
Интерактивный запрос с подтверждением, переменная окружения, stdin, командная строка; автоматическая генерация стойкого случайного пароля, когда пароль не указан.
Целостность
CRC32 исходных байтов каждого файла; аутентификация AEAD для зашифрованных архивов; конечный маркер с числом записей; самопроверяющийся аудиокодек.
Командная строка
Команды в стиле RAR (a x e l v lb t p d), извлечение отдельных файлов, папок или по подстановочным знакам, а также ключи, псевдонимы в стиле zip, подстановочные знаки, @listfiles, исключения, политики перезаписи, тихий режим, явные коды выхода.
Безопасность
Защита от zip-slip, отказ от символических ссылок, снятие битов setuid, ограниченные декодеры, атомарная запись архива, безопасность памяти Rust.
Переносимость
Windows (PowerShell, cmd), macOS, Linux; один статический исполняемый файл; побайтно идентичные результаты на каждой платформе.
Графический интерфейс
При запуске без аргументов nikpak открывает минималистичное окно перетаскивания: бросьте (или выберите) файлы или папки, чтобы сжать их наилучшим сжатием; кольцо прогресса, запоминаемая папка назначения (раздел 3.7).
Просмотрщик архивов
unNik.exe, бесплатный для всех: просмотр папок, поиск, просмотр текстовых и двоичных файлов, извлечение выбранного и удаление файлов в архивах .nik (раздел 3.9).
Скины
55 скинов окна, включая 14 рисованных сцен; панель скинов рядом с окном с кнопками Применить скин и Отмена; импорт собственных файлов Nikkomander .skin.json (раздел 3.10).
Меню файлового менеджера
Подменю «NikPak» в Explorer, Dolphin, Nemo, Nautilus и Finder: Добавить в архив, Извлечь сюда, Извлечь в отдельную папку, Открыть с помощью unNik; один архив для выбора из нескольких элементов (раздел 3.11).
2.2 nikpak и RAR бок о бок
В таблице ниже сравниваются nikpak 1.1 и RAR 7 по измерениям в этом проекте, и прямо указывается, где RAR впереди. Глава 12 обсуждает отдельные пункты.
nikpak 1.1
RAR 7
Сжатие медиа
Специализированные кодеки без потерь, выбираемые для каждого файла пробой
Записи восстановления, тома, SFX, обновление на месте
Пока нет
Да (WinRAR)
Послужной список
Новый, ещё не прошедший аудит
Десятилетия
3 Справочник по командной строке
nikpak следует синтаксису, знакомому пользователям RAR: nikpak [options] [files...]. Опции могут стоять где угодно — до имени архива или после него; -- завершает разбор опций.
3.1 Команды
Команда
Значение
a
Создать новый архив. .nik добавляется, если у имени нет расширения. Папки всегда обходятся рекурсивно.
x
Извлечь с полными путями: всё, либо только имена, папки и подстановочные знаки, указанные после имени архива (nikpak x backup.nik Docs/report.pdf извлекает один файл). Завершающий разделитель пути (или -d dir) задаёт место назначения.
e
Извлечь без путей: каждый файл попадает прямо в папку назначения.
l
Показать содержимое (всё или только совпадающие имена): атрибуты, размер, дату (UTC), имя, итоги.
v
Подробный список: добавляет CRC32 каждого файла.
lb
Простой список: одно имя на строку, предназначен для сценариев и графических оболочек.
t
Тест: распаковывает всё, проверяет каждый CRC32 и, для зашифрованных архивов, проверяет аутентификацию.
p
Вывести файлы в стандартный вывод: все или указанные (nikpak p notes.nik todo.txt | more).
d
Удалить файлы или папки (папка забирает своё содержимое) из архива. Архив перезаписывается без них; зашифрованные архивы сохраняют свой пароль. Имена обязательны.
mt
Медиа-тест: определяет файлы WAV/AIFF/MOD/BMP и показывает размер, которого достигает каждый медиа-фильтр. Ничего не записывает.
(none)
При запуске без аргументов (например, двойным щелчком по nikpak.exe) nikpak вместо этого открывает своё окно (раздел 3.7).
3.2 Опции
Стиль RAR
Стиль zip
Значение
-p
-e
Зашифровать / расшифровать, запросить пароль. Пустой ввод генерирует случайный пароль и показывает его.
-p
-P
Пароль в командной строке (виден другим пользователям машины).
-hp[password]
То же, что -p. Имена файлов в nikpak всегда зашифрованы.
-m0
.. -m5
-0
.. -9
Без сжатия, самый быстрый, быстрый, хороший, высокий (добавляет пересжатие Deflate), максимальный (по умолчанию с 1.2.1; LZMA2/PPMd, раздел 6.7). Используйте -m2, когда скорость важнее размера.
-mt
Число потоков, от 1 до 256 (по умолчанию: все ядра).
-mc- / -mc+
Все фильтры содержимого (медиакодеки и пересжатие Deflate) выключены / медиа-фильтры всегда включены. По умолчанию: автоматическая проба для каждого файла.
-r
Рекурсивный обход папок (всегда включён, принимается для совместимости).
-ep
-j
Хранить только последний компонент пути каждого аргумента.
-ep1
Не хранить имя базовой папки аргумента-папки.
-o+
-o
Перезаписывать существующие файлы без запроса.
-o-
-n
Пропускать существующие файлы без запроса.
-or
Переименовывать уже существующие извлечённые файлы: name (1).ext.
-y
Отвечать «Да» на каждый вопрос.
-x
-x
Исключить файлы; можно повторять.
-d
-d
Папка назначения для x и e.
-inul-idq
-q
Тихий режим: выводятся только ошибки.
@listfile
Читать имена файлов из текстового файла, по одному на строку.
-h-help-?
Полная справка. -V выводит версию.
Опции, которые оболочки RAR обычно передают, но которые здесь не имеют смысла (-s, -ma5, -md64m, -ibck, -idp, -rr, -ts*, -w и подобные), принимаются и игнорируются, так что существующие конфигурации инструментов продолжают работать. Всё остальное выдаёт ясное сообщение об ошибке и код выхода 7.Меню файлового менеджера добавляет несколько длинных опций (раздел 3.11): nikpak --add и --add-here сжимают указанные элементы в новый архив, nikpak --install-menu и --uninstall-menu добавляют или удаляют контекстное меню (--all-users для установки для всех пользователей), а unNik --extract, --extract-here и --extract-to управляют извлечением из меню.
3.3 Пароли подробно
Когда архив создаётся с -p, nikpak определяет пароль в следующем порядке и никогда не терпит неудачу лишь потому, что пароль не был указан:
-p или -P в командной строке: используется как есть (минимум 8 символов).
Переменная окружения NIKPAK_PASSWORD, которая не даёт паролю попасть в список процессов.
Интерактивный запрос, запрашиваемый дважды для подтверждения. Пустой ввод генерирует случайный пароль.
Без терминала (например, внутри графической оболочки) — пароль, переданный через stdin; если его нет, генерируется случайный пароль.
Сгенерированный пароль состоит из 24 символов алфавита из 56 недвусмысленных символов (без 0/O, 1/l/I), около 139 бит энтропии. Он печатается один раз в рамке на консоли. Восстановление невозможно: архив, чей пароль утерян, никто не сможет открыть.При открытии зашифрованного архива nikpak использует те же источники и затем завершается с кодом выхода 11 и поясняющим сообщением; он никогда ничего не генерирует, потому что сгенерированный пароль не мог бы совпасть.
3.4 Коды выхода
Код
Значение
Типичная причина
0
Успех
1
Предупреждение
Некоторые файлы были пропущены (нечитаемые, небезопасный путь, символическая ссылка)
2
Неустранимая ошибка
Не удаётся создать или прочитать файл, внутренняя ошибка
3
Повреждённый архив или ошибка CRC
Повреждённый или усечённый архив, несовпадение контрольной суммы
7
Ошибка командной строки
Неизвестная опция, отсутствует имя архива
10
Ничего не совпало
Ни один файл не совпал с именами или подстановочными знаками
11
Неверный или отсутствующий пароль
Неверный пароль или подделанный зашифрованный архив
3.5 Примеры
nikpak a backup.nik C:\Docs\*.txt Photos\ # create an archive
nikpak a -m5 -mt8 big.nik Projects\ # maximum, 8 threads
nikpak a -p secret.nik Taxes2026\ # encrypted, prompts
nikpak a -pMyLongPassw0rd s.nik f.pdf # password given
nikpak x backup.nik C:\Restore\ # extract with paths
nikpak e backup.nik *.jpg C:\Pics\ # only *.jpg, flat
nikpak x backup.nik Docs/report.pdf # extract ONE file
nikpak e backup.nik Docs/report.pdf -d C:\Out # one file, no path
nikpak x backup.nik Photos -d C:\Restore # one folder
nikpak l backup.nik *.pdf # list only PDFs
nikpak p backup.nik notes.txt # show a file
nikpak d backup.nik Temp *.bak # delete entries
nikpak l backup.nik # list
nikpak t secret.nik # test (asks password)
nikpak mt song.wav tracker.mod photo.bmp # which filter wins?
3.6 Интеграция с Total Commander и другими оболочками
Поскольку nikpak принимает синтаксис команд RAR (a, x, e, l, t, @listfile, -p, -ep1, -o+, -y, -m), программа, умеющая управлять внешним rar.exe, может управлять nikpak.exe. В Total Commander зарегистрируйте расширение nik в Configuration, Packer, Additional packer programs и укажите команды упаковки и распаковки на nikpak.exe. Используйте -o+ или -y для автоматического извлечения, потому что без консоли nikpak не может спросить о перезаписи и вместо этого пропустит существующие файлы. Названия пунктов меню различаются между версиями Total Commander; точные поля смотрите в его встроенной справке.
Папки с пробелами в Windows Путь в кавычках, заканчивающийся обратной косой чертой, например "C:\My Folder\", Windows разбирает неправильно (завершающая кавычка считается экранированной). Для мест назначения с пробелами используйте вместо этого -d "C:\My Folder".
3.7 Графический интерфейс
nikpak, запущенный без аргументов, например двойным щелчком по nikpak.exe, открывает небольшое окно вместо вывода справки. Оно делает одно: сжимает то, что вы на него бросите.Окно nikpak: ожидание файлов (слева) и сжатие (справа).
Бросьте файл или папку или сразу несколько на окно, либо щёлкните круг (или ссылки выбрать файлы / выбрать папку), чтобы выбрать их в диалоге; щелчок по кругу показывает две кнопки Выбрать файлы и Выбрать папку внутри кольца. Они сжимаются наилучшим сжатием (-m5) в один архив, названный по файлу (без его расширения), по папке или, для нескольких элементов, по папке, из которой они взяты. Существующий архив никогда не перезаписывается: report.nik становится report (2).nik.
Прогресс показывается крупным процентом внутри кругового индикатора, с фазой (анализ, сжатие, завершение), обработанным объёмом и временем. Кнопка Отмена под ним (или клавиша Esc) сразу останавливает долгое сжатие и удаляет незавершённый архив; окно остаётся открытым для следующего. Закрытие окна во время сжатия делает то же самое.
Готово: кольцо становится зелёным и показывает имя архива, его размер относительно оригинала и время. Показать в папке открывает его в Explorer, Finder или файловом менеджере; Сжать ещё (или щелчок по кругу) начинает следующее.
Сохранить в: папку назначения внизу можно ввести вручную или выбрать кнопкой Обзор. Она запоминается на следующий раз (Windows: %APPDATA%\nikpak\settings.txt; macOS: ~/Library/Application Support/nikpak; Linux: ~/.config/nikpak). В первый раз это рабочий стол.
Сообщество: три круглые кнопки внизу справа открывают страницы nikpak в Telegram, X и Discord (раздел 1.5).
Переключиться на unNik: круглая кнопка со стрелкой вверх, слева от кнопки i, закрывает NikPak и запускает unNik (раздел 3.9). После сжатия она и ссылка Открыть в unNik на экране готовности сразу открывают новый архив. Кнопка отключена во время сжатия.
Открыть папку назначения: кнопка-папка между полем «Сохранить в» и «Обзор» открывает эту папку в Explorer или Finder; после сжатия она открывает её с выделенным новым архивом.
Звуки: мягкий щелчок для кнопок, ссылок и опций и короткий звук для каждого действия (начало работы, успех, ошибка, отмена, переключение программы, файлы над окном). Они создаются самой программой, без звуковых файлов. Кнопка-динамик в строке заголовка выключает и включает их; по умолчанию они включены, и этот выбор общий с unNik.
Язык: кнопка внизу слева, с флагом и собственным названием языка, открывает меню десяти самых распространённых языков мира (Ethnologue 2025): English, 中文 (Mandarin Chinese), हिन्दी (Hindi), Español, العربية (Arabic), Français, বাংলা (Bengali), Português, Русский (Russian) и Bahasa Indonesia. Выбор сохраняется, и nikpak перезапускается на этом языке. В первый раз nikpak следует языку Windows (или системы), иначе — английский. Командная строка остаётся на английском.
Запуск от имени администратора: Windows не разрешает перетаскивать файлы из Explorer на программу, запущенную от имени администратора. Когда nikpak.exe запускается от имени администратора (например, из PowerShell администратора), он один раз перезапускает себя как обычный пользователь через Explorer, чтобы перетаскивание работало. Если это невозможно, окно показывает уведомление; выберите файлы кнопками.
Окно имеет размер 500 × 560 пунктов (примерно 9:10), так что снимок всего окна помещается в картинку поста X (Twitter) без обрезки. Оно без рамки: перетаскивайте его за верхнюю область; кнопки вверху справа открывают окно «О программе», сворачивают и закрывают его. Когда nikpak.exe запускается из Explorer, окно консоли, которое Windows для него открывает, закрывается автоматически; при запуске из командной строки консоль не трогается. Без графического дисплея (например, по SSH) nikpak выводит справку, как и раньше. Интерфейс использует egui/eframe и встраивает подмножества шрифтов Inter, Noto Sans SC, Noto Sans Devanagari, Noto Sans Bengali и Noto Sans Arabic (SIL Open Font License, см. assets/fonts/OFL.txt). Исполняемый файл только для командной строки собирается командой cargo build --release --no-default-features.Окно на китайском и арабском, напоминание на хинди и меню языков.Хинди, бенгали и арабский требуют шейпинга: буквы меняют форму и соединяются, гласные знаки перемещаются вокруг своего согласного, а арабский пишется справа налево. egui рисует по одному глифу на символ, что выводило бы эти языки неправильно, поэтому nikpak упорядочивает такие тексты с помощью двунаправленного алгоритма Unicode (unicode-bidi), выполняет шейпинг с помощью rustybuzz (порт HarfBuzz на Rust), растеризует их с помощью ab_glyph и рисует результат как изображение (textshape.rs). Латинские слова и числа внутри них сохраняют шрифт Inter. Длинные переводы уменьшаются, чтобы поместиться в кнопки, а рамки растут вместе с текстом. Переводы (i18n.rs) созданы с машинной помощью; приветствуется проверка носителями языка.
3.8 Лицензия и регистрация (условно-бесплатное ПО)
Бесплатно для личного некоммерческого использования, без ограничения по времени. Персональная лицензия ($19) убирает напоминание; она распространяется на все компьютеры, которые использует владелец.
Компании и организации
Одна корпоративная лицензия на рабочее место после бесплатного 40-дневного ознакомления; рабочие места — это компьютеры или пользователи, в зависимости от того, чего больше. Оптовые цены за место по образцу WinRAR: 1–9 мест $19, 10–24 $15, 25–49 $12, 50–99 $9, 100–199 $7, 200–499 $6, 500 и более $5.
Распространение
Неизменённый пакет (с LICENSE.txt и THIRD-PARTY-NOTICES.txt) можно размещать на любом сайте shareware или загрузок; добавление ключей, файлов ключей или взломов запрещено. Архивы .nik не облагаются роялти.
Напоминание пробной копии (слева), окно регистрации (в центре) и выбор файла (справа).Главное окно с маленькой кнопкой i вверху справа (слева) и окно «О программе» (справа).
Напоминание появляется, когда незарегистрированная копия открывает своё окно. В нём две кнопки, Зарегистрировать и Тестировать бесплатно, чей порядок слева/справа меняется случайным образом при каждом запуске. Тестировать бесплатно (или Esc) закрывает его; после этого nikpak работает без ограничений.
Окно регистрации запрашивает имя, адрес электронной почты и лицензионный ключ. Все три должны совпадать: ключ — это подпись имени и электронной почты. Регистр, лишние пробелы и похожие символы O/0 и I/L/1 не имеют значения. Купить лицензию открывает https://nikpak.nikkoid.com/buy.php.
После регистрации nikpak больше никогда не спрашивает на этом компьютере у этого пользователя. Лицензия хранится в %APPDATA%\nikpak\license.txt (macOS: ~/Library/Application Support/nikpak; Linux: ~/.config/nikpak). Компания может вместо этого положить файл nikpak.key рядом с nikpak.exe, что регистрирует каждого пользователя этого ПК.
Командная строка: nikpak register "Jane Doe" jane@example.com NPK1-… регистрирует; nikpak license показывает статус; nikpak unregister удаляет лицензию. nikpak -V и nikpak -help тоже показывают статус. Незарегистрированные копии печатают однострочное уведомление о пробной версии в поток ошибок (stderr), но никогда в стандартный вывод; -q подавляет его.
Как работают ключи
Лицензионный ключ выглядит как NPK1- и далее 108 символов группами по пять (Crockford base32). Он содержит тип лицензии (персональная или корпоративная), число мест и подпись Ed25519 от NIKPAK-LICENSE-1, типа, числа мест, имени и адреса электронной почты, каждый из которых нормализован (пробелы схлопнуты, нижний регистр). nikpak содержит только 32-байтовый открытый ключ, в src/license_pubkey.rs, так что изучение программы не позволяет никому создавать ключи.Ключи создаются с помощью закрытого ключа, который никогда не покидает Nikkoid LLC: либо закрытым инструментом nikpak-keygen (cargo run --release --features keygen --bin nikpak-keygen -- make --name "Jane Doe" --email jane@example.com; --company --seats 25 для компаний; newkeys создаёт новую пару ключей), либо на веб-сервере с помощью PHP-комплекта в server/ (PHP 7.2+, MySQL 5.7), который выдаёт один ключ на оплату и создаёт точно такие же ключи. server/README.md описывает настройку и процесс оплаты.
3.9 unNik, бесплатный просмотрщик архивов
unNik (unNik.exe) — вторая программа пакета. Она открывает архивы .nik, показывает их содержимое и извлекает то, что вы выберете. Она бесплатна для всех, включая компании, без регистрации и без напоминания (LICENSE.txt, раздел 2a). Установщик ставит её рядом с nikpak.exe, добавляет в меню «Пуск» и делает её программой для файлов .nik, так что двойной щелчок по архиву открывает его в unNik; unNik archive.nik делает то же самое из командной строки.unNik в ожидании архива (слева) и его встроенный просмотрщик, ищущий исходный файл (справа).Пустое окно выглядит точно как у NikPak, со стрелкой вверх в кольце. Бросьте на него архив .nik, щёлкните кольцо или выберите один из недавних архивов: окно вырастает в просмотрщик (1120 × 720, изменяемый за края, и его можно развернуть). Зашифрованные архивы сначала запрашивают свой пароль.Просмотрщик: дерево папок и сводка сжатия (слева), файлы (в центре) и сведения о выбранном файле (справа).
Навигация с помощью дерева папок, хлебных крошек, Назад, Вперёд и Вверх (Alt+Стрелка влево, Alt+Стрелка вправо, Backspace) и двойных щелчков. Поиск (Ctrl+F) находит файлы по имени во всём архиве; каждый результат показывает свою папку.
Выбор щелчком, Ctrl+щелчок, Shift+щелчок, флажками, Ctrl+A или клавишами со стрелками. Щелчок по заголовку столбца сортирует по имени, размеру, типу или дате. Правый щелчок открывает меню со всеми действиями.
Извлечь всё или выделенное (Ctrl+E): выберите место назначения (по умолчанию папка, названная по архиву, рядом с ним), сохранять ли папки, и что делать, когда файл уже существует: заменить его, сохранить оба (name (1).ext) или пропустить. Файлы, взятые из папки, создаются без пути этой папки, как в WinRAR. Чтение останавливается сразу после последнего выбранного файла.
Просмотр (F3 или двойной щелчок по текстовому файлу): текст с номерами строк, поиск с подсветкой, перенос строк и копирование; двоичные файлы в шестнадцатеричном виде. Показываются первые 16 МБ; Открыть в «Блокноте» открывает весь файл. Открыть запускает файл в его собственной программе (сначала он извлекается во временную папку).
Удалить (Del) удаляет файлы и папки из архива после подтверждения. Архив непрерывный, поэтому он перезаписывается без них во временный файл, который заменяет оригинал только когда всё прошло успешно. Зашифрованные архивы сохраняют свой пароль; остальные записи сохраняют свой медиа- или Deflate-фильтр и свой движок -m5.
Тест распаковывает весь архив и проверяет каждый файл. Панель сведений показывает размер, дату, папку, CRC32, как файл хранится и его атрибуты; для самого архива — его размер, метод и шифрование. Сводка под деревом показывает сэкономленное место.
Те же десять языков, кнопка языка, окно «О программе» (i) и кнопки сообщества, что и у NikPak. Имена файлов в любой письменности рисуются системными шрифтами как запасной вариант.
Переключиться на NikPak: круглая кнопка со стрелкой вниз, слева от кнопки i, закрывает unNik и запускает NikPak. Обе программы находятся в одной папке. Они используют один файл настроек, поэтому язык, выбранный в одной, используется другой, а уже открытое окно следует изменению в течение двух секунд.
Открыть папку назначения: кнопка слева от кнопки извлечения открывает папку последнего извлечения в Explorer или Finder (до первого извлечения — папку архива). unNik воспроизводит те же звуки, что и NikPak, со звуками открытия архива, извлечения, удаления и тестирования; его кнопка-динамик и кнопка NikPak используют одну настройку.
Извлечение выделенного (слева) и удаление файла (справа).
3.10 Скины
NikPak и unNik используют одни и те же 55 скинов окна: 41 скин Nikkomander — от Nikkoid Blue (по умолчанию) и Nikkoid Bright до Dracula, Nord, Solarized, Classic Blue, Matrix, Pizza, Christmas и 8-Bit Game — плюс 14 рисованных скинов, чьи фоны рисует сама программа: Moon, America, Pattaya Neons, Burgers Tokyo, Sushi, Amiga, MSX, Colecovision, ZX Spectrum, Cat Life, Dog Life, Mario Bros, Counter Strike и Chess.
Кнопка скинов (палитра, в строке заголовка обеих программ): открывает меню скинов, где каждый скин нарисован в своих цветах. Наведение на скин показывает его на всём окне; щелчок оставляет его; Esc или щелчок снаружи возвращает прежний скин.
Кнопка солнце / луна рядом с ней переключает между Nikkoid Blue (тёмный) и Nikkoid Bright одним щелчком.
Панель скинов стоит снаружи программы. Пока панель открыта, окно расширяется на ширину панели вправо: программа сохраняет свою панель 500 × 560, а панель находится в дополнительном прозрачном пространстве рядом, так что весь интерфейс остаётся видимым за примеряемым скином. Панель можно перетащить за строку заголовка обратно на программу или куда угодно в окне, и у неё есть кнопки Применить скин и Отмена. Щелчок по скину примеряет его на всё окно; Применить оставляет и сохраняет его для обеих программ; Отмена (или Esc, или ×) возвращает прежний скин. Щелчок по программе больше не закрывает панель. Окно unNik не расширяется.
Выбранный скин сохраняется (skin= в файле настроек) и является общим: скин, выбранный в одной программе, подхватывается другой в течение двух секунд.
Собственные скины: «Импортировать скин…» внизу меню читает файл Nikkomander .skin.json (имя и список цветов) и копирует его в папку skins рядом с файлом настроек; × на плитке импортированного скина удаляет его.
Рисованные скины уходят за интерфейс. Рисованные фоны создаются в src/skin_scenes.rs, а не CSS-градиентами, поэтому они масштабируются на любой размер окна. С версии 1.6.2 каждый проходит через обработку discreet() в src/skin.rs: изображение подтягивается к собственному локальному среднему, слегка размывается и затухает к фоновому цвету скина — больше всего за кольцом перетаскивания и столбцом текста, чуть сильнее над логотипом — так что заголовок, кольцо и текст статуса остаются чёткими на всех четырнадцати.
3.11 Меню файлового менеджера
Подменю «NikPak» в контекстном меню файлового менеджера, как у WinRAR, устанавливается установщиком (Windows: опция, отмеченная по умолчанию; Linux: nikpak --install-menu; macOS: Быстрые действия Finder).
Для файлов и папок:Добавить в архив… (запрашивает имя и папку, затем сжимает в окне NikPak) и Добавить в архив сюда (архив помещается рядом с элементами, названный как при перетаскивании на окно).
Для архивов .nik:Открыть с помощью unNik, Извлечь файлы…, Извлечь сюда и Извлечь в отдельную папку.
Несколько элементов попадают в один архив; несколько выбранных архивов извлекаются один за другим в одном окне.
Команды выполняются через unNik.exe, поэтому окно консоли не мигает; подписи следуют языку NikPak. Windows 10 показывает подменю напрямую, Windows 11 — в Показать дополнительные параметры (Shift+F10); Linux добавляет сервисные меню KDE Dolphin, действия Nemo и сценарии Nautilus, а macOS добавляет Быстрые действия Finder.
Новые опции командной строки, используемые меню:nikpak --add и --add-here (сжать указанные элементы), nikpak --install-menu, --uninstall-menu и --all-users; unNik --extract, --extract-here и --extract-to. Извлечь сюда / в отдельную папку показывает маленькое окно unNik с кольцом прогресса (поле пароля для зашифрованных архивов) и закрывает его, когда всё извлечено; предупреждения и ошибки остаются на экране.
Второй установщик, unnik--setup.exe, устанавливает только unNik (бесплатный просмотрщик) для людей, которые лишь получают архивы .nik; когда NikPak уже установлен, он устанавливает только программу, так что меню никогда не дублируются.
4 Архитектура
nikpak — это одна программа на Rust примерно из 9 600 строк (включая модульные тесты) в шестнадцати исходных файлах, плюс закрытый инструмент лицензирования nikpak-keygen. Её центральный принцип проектирования — потоковость: файлы читаются кусками по 256 КиБ, проталкиваются через цепочку писателей и никогда не удерживаются в памяти целиком (единственные исключения — пиксельные данные BMP, ограниченные 256 МиБ, и рабочие буферы кодеков по 64 КиБ).
4.1 Поток данных при создании архива
Рисунок 1: конвейер создания. Два нижних прямоугольника — входные данные для этапа над ними.Каждый этап — это реализация стандартного типажа Write, обёрнутая вокруг следующего, так что один и тот же путь кода обслуживает обычный архив, зашифрованный архив и медиа-пробу.
4.2 Карта исходного кода
Файл
Ответственность
main.rs
Точка входа. Разбирает аргументы, отправляет команду, преобразует ошибки в коды выхода. Тихо обрабатывает закрытый канал (nikpak lb x | head).
cli.rs
Написанный вручную разборщик аргументов в стиле RAR/zip, таблицы опций и полный текст -help. Библиотеки в духе Clap не могут чисто выразить ключи вроде -pSECRET или -m5.
archive.rs
Создание, вывод списка, тест, извлечение (по фильтрам или по точному выбору), удаление, печать и медиа-тест; также индекс и чтение отдельных файлов, используемые unNik. Содержит писатель и читатель потока записей, политику перезаписи и логику атомарного временного файла.
media.rs
Определение содержимого WAV, AIFF, MOD и BMP; фильтры Shuffle, Delta и MED; выбор пробой; вспомогательные функции CRC и кадрирования фрагментов.
nac.rs
Аудиокодек без потерь NAC: стереодекорреляция, предсказатели, кодирование остатков.
bits.rs
Битовый писатель и читатель со старшим битом вперёд (MSB-first), используемые NAC.
crypto.rs
Получение ключа Argon2id и писатель/читатель фрагментов XChaCha20-Poly1305.
format.rs
Константы дискового формата: магическое число, версии, типы записей, пределы KDF.
util.rs
Запрос и генерация пароля, очистка путей, сопоставление подстановочных знаков, форматирование дат и размеров.
error.rs
Тип ошибки, её коды выхода и классификация ошибок ввода-вывода (повреждение против системного сбоя).
engine.rs
Много-движковое тело уровня -m5: писатель и читатель блоков, движки LZMA2 и PPMd, проба движков (разделы 5.6, 6.7).
recomp.rs
Пересжатие Deflate контейнеров ZIP, PDF и gzip с помощью preflate (раздел 7.9).
gui.rs
Графический интерфейс: окно перетаскивания, кольцо прогресса, настройка места назначения, ссылки сообщества (раздел 3.7).
Переводы окна на десять самых распространённых языков; настройка языка (раздел 3.7).
textshape.rs
Текст с шейпингом для хинди, бенгали и арабского: упорядочение bidi, шейпинг, растеризация (раздел 3.7).
4.3 Создание архива, шаг за шагом
Проверьте место вывода. Существующий архив заменяется только с -o+ (или интерактивным «да»); иначе nikpak объясняет, что дополнение не поддерживается.
Соберите входные данные: подстановочные знаки раскрываются (PowerShell этого не делает), файлы @listfiles читаются, применяются исключения, символические ссылки и специальные файлы пропускаются с предупреждением, а сам архив никогда не добавляется в себя.
Определите пароль, если запрошено шифрование (раздел 3.3), и получите ключ с помощью Argon2id.
Запишите заголовок, затем постройте цепочку писателей: файл, буферизованный писатель, необязательный шифровальщик фрагментов, кодировщик Zstandard.
Запишите каждую запись. Медиафайлы проходят определение и пробу (глава 7); всё остальное копируется кусками по 256 КиБ, пока вычисляется CRC32.
Запишите конечный маркер с числом записей, завершите кадр Zstandard, запечатайте последний зашифрованный фрагмент и сбросьте на диск.
Переименуйтеname.nik.tmp в name.nik. Если что-то пойдёт не так раньше, объект-страж удалит временный файл, так что наполовину записанный архив никогда не заменит хороший.
4.4 Извлечение архива, шаг за шагом
Прочитайте и проверьте заголовок: магическое число, версию, флаги, метод и, для зашифрованных архивов, параметры Argon2id, которые проверяются по диапазонам до выделения памяти.
Получите пароль и выведите ключ. Первый аутентифицированный фрагмент затем подтверждает или опровергает пароль.
Пройдите по потоку записей. Имя каждой записи очищается (раздел 10.1) до любого обращения к файловой системе.
Запишите файлы с помощью create_new, установите отметки времени и права, и проверьте CRC32 восстановленных байтов. Файл, не прошедший CRC, удаляется, а не сохраняется.
Проверьте конец архива: после конечного маркера поток должен действительно закончиться, и, если архив зашифрован, последний аутентифицированный фрагмент должен быть обработан. Это ловит усечение и дописанные данные.
4.5 Память и потоки
Zstandard использует рабочие потоки для сжатия (по умолчанию все ядра, ограничение через -mt). Распаковка, аудиокодек и шифрование выполняются в вызывающем потоке. Argon2id нуждается в 64 МиБ для получения ключа, а два самых высоких уровня используют окно совпадений 128 МиБ, поэтому распаковка таких архивов требует до такого объёма памяти.
5 Формат контейнера .nik
Файл .nik — это небольшой фиксированный заголовок, за которым следует тело. Тело — это один непрерывный поток: все записи объединяются, сжимаются вместе и, при желании, шифруются. Версия 2 формата добавляет медиа-записи; архивы версии 1 остаются читаемыми.
5.1 Заголовок
Смещение
Размер
Поле
Примечания
0
8
Магическое число
89 4E 49 4B 0D 0A 1A 0A (идея PNG: обнаруживает повреждение при передаче в текстовом режиме)
случайная для каждого архива, только зашифрованные
40
19
Префикс nonce потока
случайная для каждого архива, только зашифрованные
Полный заголовок (12 байтов, или 59 байтов при шифровании) позже аутентифицируется как связанные данные каждого зашифрованного фрагмента, так что его нельзя изменить незаметно.
5.2 Записи
Внутри (расшифрованного, распакованного) потока каждый элемент — это запись. Все целые числа — little endian.
Тип
Структура
0 END
count:u64. Отмечает конец и указывает, сколько записей ему предшествует.
1 FILE
name_len:u16 name mtime:i64 mode:u32 size:u64 data[size] crc32:u32
Имена — это UTF-8 с разделителями /, не более 4096 байтов.
mtime — это секунды Unix; mode — слово прав Unix (файлы Windows получают 0644 или 0755, 0444, когда только для чтения).
CRC32 всегда вычисляется по исходным байтам, что и делает медиа-фильтры проверяемыми.
В записи MEDIA size — это исходный размер. framed_stream — это последовательность фрагментов [u32 length][bytes], завершающаяся нулевой длиной, так что читатель всегда может пропустить медиа-запись, не понимая её фильтра.
Параметры медиа
Фильтр
Параметры
Содержимое
1 Аудио
19 байтов
offset:u64 frames:u64 channels:u8 bits:u8 flags:u8 (бит 0 флага = big endian, бит 1 = со знаком)
2 Изображение
21 байт
offset:u64 width:u32 rows:u32 bpp:u8 stride:u32
3 Deflate
0 байтов
none: the framed stream holds raw segments and recompressed Deflate streams (section 7.9)
Всё до offset (заголовки, теги, палитры, паттерны MOD) и всё после области сэмплов или пикселей (завершающие фрагменты) хранится неизменным вокруг отфильтрованных данных.
5.3 Кадрирование зашифрованного тела
Когда установлен флаг шифрования, вывод zstd режется на фрагменты по 64 КиБ открытого текста. Каждый фрагмент хранится как 32-битная длина в порядке big-endian, за которой следует шифртекст, который на 16 байтов длиннее из-за тега Poly1305. Фрагмент запечатывается только когда за ним следует хотя бы ещё один байт, так что последний фрагмент никогда не бывает пустым и может быть отмечен как конечный (раздел 8.3).
5.4 Почему непрерывный поток?
Сжатие всех файлов одним потоком позволяет компрессору находить повторы между файлами, что чрезвычайно важно для деревьев исходников и коллекций документов (бенчмарк в главе 11 показывает, что непрерывный вывод RAR почти вдвое меньше его не-непрерывного вывода на 10 949 файлах). Плата — последовательный доступ: извлечение одного файла требует распаковки всего, что ему предшествует. nikpak снижает эту цену для медиа-записей, пропуская их без декодирования.
5.5 Версионирование
Байт версии сверяется с самой высокой версией, которую понимает программа. Более новый архив выдаёт сообщение Неподдерживаемая версия архива N; пожалуйста, обновите nikpak, а не вводящую в заблуждение ошибку повреждения. Неизвестные флаги, методы или медиа-фильтры отклоняются так же.
5.6 Много-движковое тело (версия 3)
Архивы, созданные с -m5, используют метод 2. Внутренний поток записей, описанный в 5.2, не меняется, но он режется — только между записями — на блоки, и каждый блок сжимается своим движком. Соединённые вместе, распакованные блоки в точности являются потоком записей одно-движкового архива, так что вывод списка, тест и извлечение работают одинаково.
Элемент
Структура
body
block*, за которым следует один байт 0
block
engine:u8 параметры, затем кадры [u32 length 1 .. 1 MiB][сжатые байты], завершающиеся нулевой длиной
PPMd вариант I (PPMd8): порядок u8, размер модели u32, метод восстановления u8 (0 = перезапуск)
Кадрирование позволяет читателю найти конец каждого блока, не доверяя декодеру, а каждый параметр проверяется по диапазонам до выделения памяти (словарь LZMA2 не более 1,5 ГиБ, модель PPMd не более 1 ГиБ, порядок от 2 до 16). При шифровании тело защищено теми же аутентифицированными фрагментами, что и любой другой архив (глава 8).
6 Движок сжатия
6.1 Почему Zstandard
Zstandard сочетает сопоставление LZ77 с энтропийным этапом, построенным на кодировании Хаффмана и конечномерной энтропии (FSE). По сравнению с алгоритмом Deflate из ZIP он находит совпадения в гораздо большем окне, моделирует литералы и длины совпадений более плотными энтропийными кодами и декодирует на скорости гигабайты в секунду. Это также открытый, широко проверенный формат, что сохраняет данные nikpak восстанавливаемыми независимыми инструментами.
6.2 Соответствие уровней
nikpak принимает и уровни в стиле RAR (-m0 .. -m5), и уровни в стиле zip (-0 .. -9) и сопоставляет их с уровнями Zstandard:
Опция
Уровень Zstandard
Характер
-m0
нет (без сжатия)
Без сжатия, без медиа-фильтров
-m1
1
Самый быстрый
-m2
3
Быстрый; около 0,9 с для 197 МБ на одном ядре (по умолчанию до 1.2.0)
Максимальный, и по умолчанию с 1.2.1: много-движковое тело (6.7) и пересжатие Deflate
Уровни в стиле zip сопоставляются так: -0 хранит без сжатия, -1–-6 используют Zstandard от 1 до 6, -7 использует 9, -8 использует 12, а -9 — то же, что -m5.
6.3 Большое окно и поиск длинных совпадений
На уровне Zstandard 15 и выше nikpak включает окно совпадений 2^27 байт (128 МиБ) и поиск длинных совпадений. Деревья исходников, наборы документов и резервные копии содержат много почти одинаковых файлов, лежащих далеко друг от друга в потоке; обычное окно 8 МиБ не может видеть через них. На тестовом наборе 197 МБ это уменьшило вывод на -m5 с 26,3 МБ до 24,4 МБ и на -m4 с 29,5 МБ до 26,8 МБ — без потери скорости для -m4 и с небольшой для -m5. Окно 2^27 укладывается в стандартный предел декодера Zstandard, так что данные может прочитать любой стандартный декодер.
6.4 Многопоточность
Кодировщик делит вход на задания, выполняемые в рабочих потоках (по умолчанию все ядра). Поэтому скорость сжатия растёт с числом ядер, а формат остаётся одним потоком. Все числа в этом руководстве измерены на одном ядре; на типичной многоядерной машине nikpak значительно быстрее, чем показано.
6.5 Целостность внутри потока
Кадр Zstandard несёт собственную контрольную сумму содержимого, nikpak добавляет CRC32 для каждого файла и конечный маркер с числом записей. Повреждённый обычный архив поэтому обнаруживается на трёх уровнях: контрольная сумма кадра, CRC каждого файла и конечный маркер.
6.6 Режим без сжатия
-m0 записывает записи без сжатия. Это полезно для уже сжатых данных, и это также единственный режим, в котором медиа-фильтры намеренно обходятся: пользователь, запрашивающий без сжатия, не ожидает, что данные будут преобразованы.
6.7 Максимальный уровень: LZMA2 и PPMd
Zstandard — правильный движок для скорости, но на самых сильных настройках он всё ещё на несколько процентов уступает LZMA2 на исходном коде и документах и заметно уступает PPMd на прозе. Поэтому с версии 1.2 уровень -m5 строит архив из двух блоков (формат в 5.6):
Двоичный блок. Папки, двоичные файлы, медиа-записи и записи с пересжатым Deflate сжимаются с помощью LZMA2: пресет 9, приятная длина 273, глубина поиска совпадений 32 и словарь, подобранный под данные (от 1 до 128 МиБ).
Текстовый блок. Файлы, чьи первые 64 КиБ не содержат нулевого байта и почти не содержат управляющих символов (исходный код, текст, CSV, HTML, XML ...), попадают во второй блок. Четыре подряд идущих участка по 1 МиБ этих файлов пробно сжимаются PPMd вариант I (порядок 8, модель 192 МиБ) и LZMA2, настроенным на текст (lc 4, pb 0), и побеждает меньший результат. Проза благоприятствует PPMd; большие деревья исходников со множеством почти идентичных файлов благоприятствуют LZMA2, потому что он может копировать длинные повторы между файлами.
Порядок. Внутри каждого блока файлы сортируются по расширению, затем по имени файла, как делает 7-Zip, так что идентичные или похожие файлы оказываются соседями. Вместе с непрерывной пробной выборкой это сделало общий набор данных на 7,5 % меньше.
«Экстремальные» настройки LZMA2 были измерены и отвергнуты: на XML электронных таблиц они были до десяти раз медленнее и не меньше. -m5 выполняется в одном потоке, независимо от -mt.
7 Медиа-интеллект
Компрессор общего назначения видит байты. Он не знает, что файл WAV — это осциллограмма, чей следующий сэмпл предсказуем по предыдущим, или что соседние пиксели фотографии почти равны. Медиа-слой nikpak даёт это знание: он распознаёт такие файлы, применяет преобразование без потерь, раскрывающее избыточность, и позволяет компрессору (или специализированному кодеку) её использовать. Именно здесь nikpak больше всего выигрывает у RAR.
7.1 Определение по содержимому
Определение смотрит на первые байты каждого файла размером не менее 8 КиБ и никогда не доверяет расширению, так что WAV, переименованный в .dat, всё равно находится, а текстовый файл с именем .wav — нет.
Тип
Как распознаётся
Что фильтруется
WAV
RIFF..WAVE, фрагмент fmt с целочисленным PCM (формат 1, или WAVE_FORMAT_EXTENSIBLE с подформатом PCM), 8/16/24/32 бита, от 1 до 8 каналов, согласованное выравнивание блоков; затем фрагмент data
Область сэмплов. Нулевая, завышенная или поддельная длина данных ограничивается размером файла; оставшиеся байты и завершающие фрагменты сохраняются как есть.
AIFF / AIFC
FORM..AIFF или AIFC (сжатие NONE или twos), фрагменты COMM и SSND, сэмплы со знаком в порядке big-endian
Область звуковых данных.
ProTracker MOD
Подпись по смещению 1080: M.K., M!K!, FLT4, 4CHN, 6CHN, 8CHN, FLT8, OCTA или CD81
Область 8-битных сэмплов после данных паттернов (раздел 7.6).
BMP
BM, заголовок DIB не менее 40 байтов, без сжатия, 8, 24 или 32 бита на пиксель, строки пикселей, помещающиеся в файл, область от 4 КиБ до 256 МиБ
Строки пикселей (раздел 7.7).
Не обрабатываются и поэтому хранятся с обычным сжатием: WAV с плавающей точкой, ADPCM и другое сжатое аудио, RLE или битовые BMP, а также трекерные форматы, кроме ProTracker MOD. Уже сжатые медиа, такие как MP3, JPEG, FLAC, PNG и MP4, вообще не распознаются и остаются в покое, поскольку их преобразование не помогло бы.
7.2 Проба: выбор лучшего фильтра для каждого файла
Ни одно преобразование не является лучшим для каждого файла. Предсказательное кодирование выигрывает на записанной музыке; разделение байтовых плоскостей выигрывает на аудио, полученном из 8-битного компандированного источника (где встречается лишь около тысячи различных 16-битных значений); обычное сжатие выигрывает на тишине и на очень повторяющихся трекерных сэмплах. Поэтому nikpak измеряет, а не угадывает.
Возьмите выборку: всю область сэмплов, если она до 3 МиБ, иначе три окна по 768 КиБ на 5 %, 45 % и 85 % аудио. Для изображений — первые строки, примерно до 4 МиБ.
Сожмите выборку обычным Zstandard уровня 3 (базовый уровень) и каждым применимым фильтром: NAC, Shuffle и Shuffle+Delta для 16/24/32-битного аудио; NAC и Shuffle+Delta для 8-битного аудио; MED для изображений.
Сохраните фильтр с наименьшей оценкой, но только если он превосходит базовый уровень хотя бы на 2 %. Иначе файл хранится с обычным сжатием.
Запишите файл победителем. Всё это происходит для каждого файла, так что один архив может содержать WAV, закодированные разными методами, рядом с обычными файлами.
nikpak mt выполняет то же измерение на целом файле и печатает таблицу — именно так исследовался бенчмарк в главе 11. Среди опций -mc- отключает фильтры, а -mc+ принудительно включает фильтр по умолчанию без пробы.
Без потерь, проверяемо и отключаемо Каждый фильтр точно обратим. CRC32, хранящийся с каждой записью, вычисляется по исходным байтам и проверяется при извлечении, кодировщик NAC проверяет каждый блок во время записи (раздел 7.4), а -mc- выключает весь слой.
7.3 Аудиокодек NAC
NAC (nikpak audio codec) — это блочный кодек без потерь для целочисленного PCM. Он принадлежит к тому же семейству, что и FLAC: линейное предсказание с последующим кодированием Райса. У него собственный битовый поток, спроектированный для этого архива, и он используется для WAV, AIFF и сэмпловых данных файлов MOD.Рисунок 2: кодирование одного блока из 4096 кадров сэмплов.
Блоки и стереодекорреляция
Аудио режется на блоки по 4096 кадров сэмплов, каждый кодируется независимо, что делает кодек устойчивым (ошибка не может распространиться) и позволяет кодировщику адаптироваться к меняющемуся материалу. Для стерео кодировщик выбирает одно из четырёх представлений на блок:
Режим
Кодируемые каналы
Восстановление
0
Левый, Правый
прямое
1
Левый, Боковой
R
= L - S
2
Боковой, Правый
L
= R + S
3
Средний, Боковой
sum = (M << 1) | (S & 1), L = (sum + S) >> 1, R = (sum - S) >> 1
где Side = L - R и Mid = (L + R) >> 1. Боковому каналу нужен на один бит больше, чем обычному, и он кодируется с bits + 1. Режим выбирается дёшево: кодировщик суммирует абсолютные значения остатка фиксированного предсказателя 2-го порядка для L, R, M и S и берёт пару с наименьшей суммой. Для записей, чьи каналы сильно коррелированы, Mid/Side обычно экономит несколько процентов.
Типы подкадров
Каждый закодированный канал блока хранится как один из четырёх подкадров — тот, который меньше всего:
Тип
Применение
Цена
Константа
Все сэмплы равны (цифровая тишина)
2 + биты разрядности сэмпла на весь блок
Дословно
Шумоподобный материал или запасной вариант для безопасности
n x битов разрядности
Фиксированный
Полиномиальный предсказатель порядка от 0 до 4
прогревочные сэмплы + остатки
LPC
Линейный предсказатель порядка от 1 до 32 с передаваемыми коэффициентами
коэффициенты + прогрев + остатки
Потерянные биты. Если младшие биты каждого сэмпла в блоке всегда нулевые (8-битная запись, хранимая в 16-битных контейнерах, или квантованный сигнал), они удаляются, а их количество хранится в 5 битах.
Первые order сэмплов блока хранятся дословно как прогревочные значения.
Линейное предсказательное кодирование (LPC)
Для тональной и гармонической музыки предсказатель, чьи коэффициенты подогнаны под блок, гораздо лучше фиксированного полинома. Кодировщик вычисляет их следующим образом:
Примените окно Тьюки (сужение на первой и последней четверти) к блоку, чтобы его края не искажали статистику.
Вычислите автокорреляциюr[0..32] сигнала с окном.
Выполните рекурсию Левинсона–Дурбина, которая даёт оптимальный набор коэффициентов для каждого порядка от 1 до 32 за один проход: k = (r[i] - sum a[j] r[i-j]) / err, a[i] = k, a[j] = a[j] - k a[i-j], err = err (1 - k^2).
Квантуйте вещественные коэффициенты в целые с точностью 12, 14 или 15 бит (в зависимости от разрядности сэмпла), выбирая масштаб-степень двойки (shift, от 0 до 20), чтобы наибольший коэффициент как раз помещался. Округление использует обратную связь по ошибке, так что ошибки квантования не накапливаются между коэффициентами.
Оцените несколько порядков (набор зависит от уровня усилий, см. ниже), вычислите остаток каждого и сохраните тот, у которого наименьший оценённый общий размер, включая цену передачи его коэффициентов.
Сам предсказатель — это чисто целочисленная арифметика, которую и выполняет декодер:
e[i] = x[i] - pred[i] (n = order; the sum uses 64 bits)
Плавающая точка используется только кодировщиком для решения, какие целые коэффициенты передать. Декодер никогда не касается плавающей точки, поэтому декодирование побитно точно на любом процессоре и любом компиляторе.
Кодирование остатков
Ошибки предсказания отображаются в беззнаковые числа зигзагообразным преобразованием (u = (e << 1) XOR (e >> 63), так что малые положительные и отрицательные значения становятся малыми числами) и кодируются секционированными кодами Райса. Остаток блока делится на 2^p секций (p от 0 до 8, выбирается кодировщиком); каждая секция получает свой параметр Райса k (5 бит). Значение записывается как u >> k в унарном коде (столько нулей и единица), за которым следуют младшие k бит. Лучший k секции выводится из суммы её значений, так что цену каждого кандидата-предсказателя можно дёшево оценить по текущим суммам, а не кодируя его.
Уровни усилий
Уровень архива (опция -m) выбирает, сколько порядков LPC пробуется на блок. Больше порядков означает чуть меньший результат и более медленный кодировщик; скорость декодера та же.
Уровень архива
Усилие NAC
Пробуемые порядки LPC
-m1
0
8,
16
-m2,
-m3
1
4,
8, 12, 16, 24, 32
-m4,
-m5
2
2,
4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32
Фиксированные предсказатели порядка от 0 до 4 пробуются всегда. В бенчмарке уровень усилий изменил результат стереомузыки менее чем на 0,05 %: большой выигрыш даёт само использование предсказания.
VERBATIM : wasted:5 samples:(n x (width - wasted))
FIXED : wasted:5 order:3 warm-up residual
LPC : wasted:5 order-1:5 precision-1:4 shift:5
coefficients warm-up residual
residual := partition-order:4 per partition: k:5 Rice-coded values
Каждый блок хранится в архиве с 32-битной длиной впереди, так что декодер всегда знает, где начинается следующий блок.
7.4 Самопроверка
Запись архива — единственный шанс обнаружить ошибку кодировщика, поэтому кодировщик NAC не доверяет сам себе. Закодировав каждый блок, он декодирует блок снова и сравнивает результат с исходными сэмплами. При любом расхождении он перекодирует блок дословно (что не может не удаться) и проверяет снова; если не удаётся даже это, архивирование останавливается с явной ошибкой и предложением использовать -mc-. Путь отката проверяется модульными тестами, которые принудительно включают дословное кодирование для каждой комбинации разрядности и числа каналов, и этот механизм превращает возможную тихую потерю данных в обнаруженное, восстановимое состояние.Вдобавок декодер подвергается фаззингу: в модульных тестах ему скармливаются тысячи блоков случайных байтов и блоков с перевёрнутыми битами, и он должен возвращать ошибку, не паникуя и не выделяя необоснованных объёмов памяти. В ходе разработки это нашло реальную ошибку (для 32-битного материала поиск параметра Райса мог оказаться пустым и откатиться к параметру, который дал бы многогигабайтный код); она исправлена и покрыта тестом.
7.5 Shuffle и Shuffle+Delta
Некоторое аудио не поддаётся предсказанию. Галерейные файлы WAV, используемые в бенчмарке, 16-битные, но содержат лишь около тысячи различных значений сэмплов, потому что они получены из компандированного 8-битного источника. Предсказатель не может этим воспользоваться, и FLAC сжимает их до 84 % от оригинала, тогда как обычному Zstandard нужно 63 %. Помогает расположение байтов так, чтобы компрессор видел однородные данные:
Shuffle разделяет байты сэмплов на плоскости: все младшие байты канала 0, затем все старшие байты канала 0, затем канал 1 и так далее, блоками по 32768 кадров. Плоскость старших байтов гладкая, а плоскость младших байтов имеет очень ограниченный алфавит; энтропийный кодер Zstandard моделирует каждую гораздо лучше, чем чередующуюся смесь.
Shuffle+Delta сначала заменяет каждый сэмпл его разностью с предыдущим сэмплом того же канала (по модулю разрядности сэмпла, так что это точно обратимо, с переносом состояния между блоками), а затем перемешивает. Это помогает, когда сигнал гладкий, но недостаточно предсказуемый, чтобы выиграл NAC.
На 35 галерейных файлах архив с лучшим фильтром для каждого файла (выбранным пробой) составляет 51 % исходного размера на -m2 и 47 % на -m5, против 63 % у обычного Zstandard.
7.6 Файлы ProTracker MOD
Модуль MOD — это заголовок на 1084 байта (название, 31 дескриптор сэмплов, таблица порядка паттернов из 128 записей и 4-байтовая подпись по смещению 1080), затем данные паттернов, затем сырые 8-битные сэмплы со знаком всех инструментов. nikpak вычисляет, где начинаются сэмплы и какова их длина:
patterns = max(order table) + 1
sample_start = 1084 + patterns * 256 * channels (4 ch: 1024 B per pattern)
sample_bytes = sum of (length in words * 2) over the 31 descriptors,
clamped to the end of the file
Заголовок и паттерны хранятся как есть (компрессор хорошо справляется с этими повторяющимися нотами), а область сэмплов рассматривается как один монофонический 8-битный поток со знаком для пробы. Для каждого файла побеждает NAC, Shuffle+Delta или обычное сжатие: сэмплированные инструменты в основном благоприятствуют NAC, а на некоторых модулях (например, с очень короткими или очень повторяющимися сэмплами) выигрывает обычное сжатие. Усечённые модули обрабатываются ограничением области фактически присутствующими данными.
7.7 Изображения BMP
Несжатый BMP хранит строки пикселей, дополненные до кратного четырём байтам. Фильтр работает в четыре шага:
Разделите область пикселей на одну плоскость на канал (B, G, R и A для 32-битного), запоминая байты дополнения каждой строки отдельно.
Декоррелируйте цвет. Вычтите зелёную плоскость из синей и красной плоскостей (по модулю 256). На фотографиях три канала сильно коррелированы, поэтому разности малы.
Предскажите каждый пиксель по его соседям предсказателем MED (median edge detector), тем же, что используется в кодере изображений LOCO-I: для левого a, верхнего b и верхне-левого c предсказание равно min(a,b), если c >= max(a,b), max(a,b), если c <= min(a,b), и a + b - c иначе. Ошибка предсказания заменяет пиксель (по модулю 256). На краях предсказатель следует за краем; на гладких градиентах он экстраполирует градиент.
Объедините плоскости остатков и байты дополнения и позвольте Zstandard сжать их. Гладкие области становятся последовательностями почти нулевых байтов.
Декодер в точности обращает шаги. 8-битные BMP пропускают цветовой шаг; затем проба решает, помогает ли предсказание для этой палитры, поскольку предсказание индексов палитры имеет смысл только для оттенков серого или плавно упорядоченных палитр. Файлы BMP больше 256 МиБ не фильтруются, чтобы ограничить использование памяти.
7.8 Почему это лучше RAR
RAR сжимает медиа своим общим движком совпадений и Хаффмана плюс небольшим набором байтовых фильтров. nikpak вместо этого даёт аудио настоящий предсказательный кодек с поблочной стереодекорреляцией и адаптивным кодированием Райса, даёт изображениям полноценный двумерный предсказатель с цветовой декорреляцией и выбирает для каждого файла измерением. Следствие видно в бенчмарке: на 12–15 % меньше на аудио любого рода, на 13 % на трекерной музыке и на 39 % на фотографиях, а результат NAC для стереодорожки в пределах 0,2 % от специализированного кодировщика FLAC.
7.9 Офисные документы, PDF и gzip: пересжатие Deflate
Современные офисные файлы — это ZIP-архивы XML (docx, xlsx, pptx, odt, ods), а файлы PDF хранят свои страницы в потоках Deflate (FlateDecode). Их содержимое поэтому уже сжато, и никакой архиватор не может сильно его уменьшить: в бенчмарке 1.1 6,6 МБ файлов .xlsx сжимались 7-Zip лишь до 5,6 МБ. nikpak 1.2 устраняет это препятствие.
Определение по содержимому. Локальный заголовок ZIP (PK\x03\x04) в начале файла, %PDF- или заголовок gzip; расширение никогда не используется.
Декодирование. Каждый поток Deflate находится (записи ZIP с методом 8, потоки PDF с заголовком zlib, каждый член gzip) и анализируется с помощью preflate (preflate-rs от Microsoft). preflate возвращает открытые данные плюс небольшую запись поправок, которая точно описывает, как исходный кодировщик делал свой выбор, каким бы этот кодировщик ни был.
Хранение. Файл хранится как последовательность сырых сегментов и пар (открытые данные, поправки). Открытый XML или описание страницы затем попадает в непрерывный поток, где LZMA2 сжимает его до доли его размера в Deflate.
Проверка. Прежде чем использовать результат, nikpak перестраивает каждый поток Deflate и сравнивает длину и CRC32 всего файла с оригиналом. Если что-то отличается, или preflate терпит неудачу или паникует на повреждённом файле, файл просто хранится обычным образом.
Извлечение. Потоки Deflate воссоздаются бит в бит, так что извлечённый .docx или .pdf побайтно идентичен, а его CRC32 проверяется, как и для каждой записи.
На офисном наборе из раздела 11.7 именно это делает nikpak меньше любого другого архиватора. В 6,6 МБ файлов .xlsx после декодирования содержится 71 МБ XML, и этот XML сжимается гораздо лучше, чем это делал Deflate. Цена — время: preflate анализирует примерно 15 МБ открытых данных в секунду. Поэтому пересжатие используется только на -m4 и -m5, где оно окупается (измерено: -m3 давал 0,5 % за шестикратное время). Пределы: файлы до 512 МиБ, а на поток — до 512 МиБ открытых данных и 64 МиБ поправок. -mc- выключает это.
8 Шифрование
Шифрование nikpak построено целиком из стандартных, хорошо изученных компонентов (реализации Argon2id и XChaCha20-Poly1305 от RustCrypto). Никакой примитив не был изобретён для этого проекта; работа состоит в их правильном сочетании.
8.1 Модель угроз
Проектирование предполагает злоумышленника, который получает файл архива и может не спеша изучать и изменять его, а также может пробовать неограниченное число паролей офлайн. nikpak стремится гарантировать:
Конфиденциальность содержимого файлов и всего, что их касается: имён, размеров, отметок времени, прав и числа файлов.
Целостность и подлинность: любое изменение архива — данных, заголовка, порядка данных или их длины — обнаруживается до того, как неверные данные будут приняты.
Стойкость к подбору: каждый перебор пароля делается настолько дорогим, насколько это практично.
Он не скрывает, что архив существует, ни его приблизительный размер, и не может защитить от вредоносного ПО на машине, создающей или открывающей архив, или от слабого пароля.
8.2 От пароля к ключу: Argon2id
Пароль — плохой ключ: короткий, предсказуемый и набранный человеком. Он превращается в 256-битный ключ с помощью Argon2id, победителя Password Hashing Competition и алгоритма, стандартизированного в RFC 9106. Argon2id намеренно ресурсоёмкий по памяти: вычисление одного ключа требует большого блока памяти, который заполняется, а затем многократно читается в зависящем от данных порядке. nikpak использует профиль RFC с низкой памятью:
Параметр
Значение
Значение
Память
64 МиБ
Каждая попытка требует 64 МиБ быстрой памяти
Проходы
3
Память обрабатывается три раза
Дорожки
4
Степень параллелизма внутри одного вывода
Соль
16 случайных байтов
Новая для каждого архива: одинаковые пароли дают разные ключи, и заранее вычисленные таблицы бесполезны
Вывод
32 байта
Ключ XChaCha20-Poly1305
Ресурсоёмкость по памяти — то, что отличает Argon2id от более старого PBKDF2 (используемого RAR5 и AES-режимом ZIP): PBKDF2 почти не требует памяти, так что видеокарта или специализированный чип могут проверять огромное число попыток параллельно. С Argon2id аппаратура злоумышленника должна обеспечивать 64 МиБ на каждую параллельную попытку, что устраняет большую часть этого преимущества. Цена для законного пользователя — доля секунды, выплачиваемая один раз за архив.Параметры хранятся в заголовке, так что будущие версии могут повышать их, не ломая старые архивы. При чтении они сначала проверяются по диапазонам (память 8 x дорожки до 1 ГиБ, проходы от 1 до 64, дорожки от 1 до 64), так что вредоносный архив не может заставить nikpak выделить нелепые объёмы памяти до проверки пароля.
8.3 XChaCha20-Poly1305 в конструкции STREAM
Основные данные защищаются XChaCha20-Poly1305, шифром с аутентифицированным шифрованием и связанными данными (AEAD): ChaCha20 даёт потоковый шифр с 256-битным ключом, вариант X расширяет его nonce до 192 бит (достаточно, чтобы выбирать случайно без повторов), а Poly1305 добавляет 128-битный аутентификационный тег к каждому запечатанному сообщению. ChaCha20 быстр на любом ЦП без специальных инструкций и, в отличие от табличного AES, по своей природе свободен от утечек по кэш-таймингу.Архив гораздо больше одного сообщения, поэтому nikpak использует конструкцию STREAM (ту же, что и современные инструменты шифрования файлов): данные режутся на фрагменты по 64 КиБ, и фрагмент с номером i запечатывается под nonce
nonce (24 bytes) = random prefix (19 bytes)
| chunk counter (4 bytes, big endian)
| last-chunk flag (1 byte)
Это даёт сразу три гарантии. Каждый фрагмент имеет уникальный nonce, что существенно для потоковых шифров. Поскольку счётчик — часть nonce, перестановка или дублирование фрагментов приводит к провалу аутентификации. Поскольку последний фрагмент несёт другой флаг, усечение архива, даже ровно по границе фрагмента, приводит к провалу аутентификации: новый последний фрагмент был запечатан как не-последний. 19-байтовый префикс случаен для каждого архива.Кроме того, полный заголовок архива (версия, флаги, метод, параметры Argon2id, соль и префикс nonce) передаётся как связанные данные каждому фрагменту. Он аутентифицируется, но не шифруется; переворот любого его бита делает недействительными все фрагменты. Это также блокирует атаки понижения версии, пытающиеся ослабить хранимые параметры.
до 64 КиБ открытого текста; хранится как u32 length + шифртекст + 16-байтовый тег
Накладные расходы размера
около 0,03 % (20 байтов на 64 КиБ), измерено 0,03 % на наборе данных 222 МБ
Накладные расходы скорости
измерено: всего +0,3 с на наборе данных 222 МБ (0,92 с вместо 0,64 с), включая получение ключа
Неверный пароль
Обнаруживается на первом фрагменте; открытый текст не производится
8.4 Что наблюдатель может и не может видеть
Видимо без пароля
Защищено
Магическое число, версия, флаги и метод сжатия
Имена файлов и структура папок
Параметры Argon2id, соль и префикс nonce
Размеры файлов, отметки времени и права
Общий размер архива и число фрагментов
Число файлов
Тот факт, что это архив nikpak
Всё содержимое, включая то, содержит ли оно медиа
Одно следствие сжатия перед шифрованием — то, что размер архива отражает, насколько сжимаемы данные. Это присуще каждому архиватору, который сжимает и шифрует; это имеет значение, только если злоумышленник может управлять частью данных и наблюдать размер, что не относится к архивированию файлов.
8.5 Обработка паролей
Минимальная длина. 8 символов при создании архива; более короткие пароли отклоняются с объяснением.
Подтверждение. Интерактивный запрос спрашивает дважды, не выводит набранные символы и отклоняет несовпадение.
Генерация. Без пароля nikpak берёт 24 символа из алфавита из 56 символов, исключающего похожие (0/O, 1/l/I), используя выборку с отбраковкой на криптографически стойком генераторе случайных чисел операционной системы, так что ни один символ не вероятнее другого. Это 24 x log2(56), около 139 бит энтропии, и показывается один раз, в ясно отмеченной рамке.
Гигиена памяти. Выведенный ключ и строки пароля стираются из памяти, когда больше не нужны (крейт zeroize).
Каналы. Командная строка (-p), переменная окружения NIKPAK_PASSWORD, интерактивный запрос или stdin, когда нет терминала. Форма командной строки удобна, но видна в списке процессов; остальные формы предпочтительнее.
8.6 Атаки-тесты
Следующие манипуляции с зашифрованными архивами выполнялись против готовой программы. Все были обнаружены до принятия каких-либо неверных данных:
Манипуляция
Результат
Перевернуть один байт в середине шифртекста
Отклонено: провал аутентификации (код 11)
Перевернуть байт соли в заголовке
Отклонено (заголовок — это связанные данные, и ключ меняется)
Изменить байт метода в заголовке
Отклонено
Усечь файл на 100 байтов
Отклонено как повреждённое (код 3)
Удалить последний фрагмент ровно по границе фрагмента
Отклонено: новый последний фрагмент не имеет конечного флага
Поменять местами два фрагмента
Отклонено: несовпадение счётчика
Указать неверный пароль
Отклонено на первом фрагменте (код 11)
Подать случайный файл как архив
Отклонено: плохая подпись (код 3)
Остаточные риски, изложенные прямо Слабый пароль всегда можно подобрать; Argon2id делает это дорогим, но не может спасти password123. nikpak не проходил независимого аудита. Он не может защитить от кейлоггеров, вредоносного ПО или от кого-то, читающего память работающего процесса. Для данных, чьё раскрытие было бы серьёзно вредным, сначала поручите криптографу проверить реализацию.
9 Квантовая стойкость
Квантовые компьютеры серьёзно угрожают одной криптографии и почти не угрожают другой. nikpak спроектирован на той стороне, которая почти не затронута.
9.1 Что меняют квантовые компьютеры
Алгоритм
Эффект
Кто затронут
Шор (1994)
Раскладывает целые числа на множители и вычисляет дискретные логарифмы за полиномиальное время
RSA, Диффи–Хеллман, DSA, криптография на эллиптических кривых: взломаны большим квантовым компьютером
Гровер (1996)
Ищет в неструктурированном пространстве из N элементов примерно за корень из N шагов
Симметричные ключи и хеш-функции: эффективная длина ключа уменьшается вдвое
Алгоритм Шора — драматичный: он взломал бы каждую систему, опирающуюся на математику открытых ключей, поэтому правительства и органы стандартизации переходят на постквантовые алгоритмы с открытым ключом, такие как ML-KEM (FIPS 203). Алгоритм Гровера — мягкий: 256-битный ключ даёт около 128 бит безопасности против него, а итерации Гровера по своей сути последовательны, так что распределение работы по многим квантовым машинам даёт ускорение лишь в корень из их числа.
9.2 Позиция nikpak
Компонент
Примитив
Квантовое воздействие
Шифрование
XChaCha20, 256-битный ключ
Лучшая известная атака: Гровер, около 2^128 операций. Вне досягаемости.
Аутентификация
Poly1305, 128-битный тег, ключ из 256-битного секрета
Математика открытых ключей не задействована
Пароль в ключ
Argon2id, 64 МиБ, 3 прохода
Гровер может в лучшем случае вдвое уменьшить энтропию пароля, и каждая итерация потребовала бы вычисления ресурсоёмкой по памяти функции
Случайность
CSPRNG операционной системы
Не затронута
Криптография с открытым ключом
Отсутствует
Алгоритму Шора нечего атаковать
256-битный симметричный ключ — эталон для высшей категории безопасности (категория 5) постквантовой стандартизации NIST: алгоритмы с открытым ключом, стандартизированные NIST, оцениваются по тому, насколько близко они соответствуют сложности полного перебора 256-битного ключа AES. Иными словами, шифрование данных nikpak уже находится на той стойкости, к которой стремятся постквантовые стандарты.
9.3 А что насчёт пароля?
Пространство ключей шифра — 256 бит, но ключ выводится из пароля, так что реальная стойкость — это меньшее из энтропии пароля и 256 бит. Против квантового противника энтропия пароля, в лучшем для злоумышленника случае, уменьшается вдвое:
Пароль
Энтропия
Классический перебор
Перебор Гровера (в лучшем случае)
сгенерированный nikpak (24 символа)
около 139 бит
около 2^139 попыток
около 2^70 итераций, каждая из которых требует когерентного вычисления Argon2id на 64 МиБ
Шесть случайных слов Diceware
около 77 бит
около 2^77 попыток
около 2^39 итераций той же дорогой схемы
Выбранный человеком 10-символьный пароль
обычно 30–45 бит
выполнимо
выполнимо
Вывод знакомый, но сформулированный резче: слабое место — пароль, а не шифр. Используйте сгенерированный пароль или длинную случайную парольную фразу, и архив устоит и против классических, и против квантовых атак в любом обозримом будущем. Argon2id помогает в обоих мирах, потому что цена каждой попытки определяется в основном памятью, которую алгоритм Гровера не делает дешевле.
9.4 «Собрать сейчас, расшифровать позже»
Часто цитируемая квантовая угроза: противник записывает зашифрованные данные сегодня, а расшифровывает их, когда появится квантовый компьютер. Для систем, обменивающихся ключами с помощью RSA или эллиптических кривых, таких как соединения TLS или шифрование электронной почты, это реально. У архива nikpak нет обмена ключами: его ключ берётся из секрета, который никогда не покидает голову пользователя или менеджер паролей. Сохранённую копию позже можно открыть, только угадав этот секрет, и квантовые компьютеры не делают это принципиально легче.
9.5 Честные пределы и дорога вперёд
«Квантовая стойкость» означает, что ни один известный квантовый алгоритм не превосходит общий перебор против этих примитивов. Это не доказательство; криптоанализ ChaCha20 и Argon2 продолжается, а формат версионируется, так что параметры или алгоритмы можно менять.
Если когда-нибудь будет добавлен обмен открытыми ключами (шифрование архива на ключ получателя), он будет использовать гибридную схему — X25519 в сочетании с ML-KEM, так что она безопасна, если устоит любой из компонентов.
Квантовая стойкость не защищает от ошибок реализации. См. разделы 8.6 и 10.
10 Укрепление защиты и устойчивость
Архиватор читает файлы, написанные незнакомцами, и пишет файлы на диск своего пользователя, что делает его классической целью. nikpak рассматривает каждый архив как недоверенный вход.
10.1 Безопасное извлечение
Обход пути («zip slip»). Имя каждой записи нормализуется: обратные косые черты становятся косыми, пустые компоненты и . отбрасываются, а любой компонент .. приводит к пропуску записи с предупреждением. Абсолютные имена теряют свой корень, так что /etc/passwd извлекается внутри папки назначения.
Имена Windows. При работе в Windows компоненты, содержащие < > : " | ? * или управляющие символы, заканчивающиеся пробелом или точкой, или равные зарезервированному имени устройства (CON, PRN, AUX, NUL, COM1-9, LPT1-9), отклоняются.
Символические ссылки. Перед записью проверяется каждый существующий компонент целевого пути ниже места назначения; ссылка никогда не разыменовывается. Существующий файл сначала удаляется, а новый создаётся с помощью create_new, который отказывается открывать существующий путь, так что ссылку нельзя использовать для перенаправления записи.
Привилегированные биты. Биты setuid, setgid и sticky никогда не восстанавливаются; права маскируются до обычных битов rwx.
Неудавшиеся файлы. Файл, чей CRC32 не совпадает, удаляется, а не остаётся.
Собранный вручную архив, содержащий ../../evil.txt, /tmp/evil.txt, ..\..\evil.txt и ok/../../evil.txt, был извлечён в тестах: ничто не вышло за пределы места назначения, небезопасные записи были сообщены и пропущены, а подложенная символическая ссылка в месте назначения была отклонена.
10.2 Ограниченные декодеры
Параметры Argon2id проверяются по диапазонам до любого выделения памяти (раздел 8.2).
Зашифрованные фрагменты должны иметь длину от 16 байтов до 64 КиБ + 16; имена — не более 4096 байтов; аудиоблоки должны объявлять правдоподобную длину; области BMP ограничены 256 МиБ; унарные коды Райса ограничены сверху.
Аудио- и медиадекодеры получали тысячи случайных и перевёрнутых по битам входов в модульных тестах и должны возвращать ошибку, никогда не паниковать и не аварийно завершаться.
Собственный код nikpak не содержит блоков unsafe, а проверка границ Rust превращает любую логическую ошибку, которая в C была бы ошибкой повреждения памяти, в чистое завершение с ошибкой.
nikpak не ограничивает коэффициент расширения архива, так что, как и любой архиватор, намеренно созданная «бомба сжатия» может заполнить диск при извлечении. Если это важно, сначала проверяйте неизвестные архивы командой t.
10.3 Безопасное создание и честные ошибки
Архив записывается в name.nik.tmp и переименовывается только по завершении; страж удаляет временный файл при любой неудаче, так что прерванный запуск никогда не оставляет наполовину записанный или заменённый архив.
Если файл становится короче во время архивирования, nikpak прерывается с явным сообщением, а не записывает несогласованную запись. Нечитаемые файлы, символические ссылки и специальные файлы пропускаются с предупреждением (код выхода 1), и архив никогда не добавляется в себя.
Ошибки классифицируются так, чтобы сценарии могли реагировать: ошибка контрольной суммы или кадра внутри архива — это повреждение (код 3), провал аутентификации — неверный пароль или подделка (код 11), отказ записи — неустранимая ошибка (код 2).
11 Бенчмарки
Эта глава сообщает измерения, а не заявления. Она точно описывает, что измерялось, включает результаты, которые не в пользу nikpak, и даёт команды, необходимые для повторения всего.Разделы 11.1–11.6 измерялись с nikpak 1.1.0, чей -m5 ещё использовал Zstandard. Раздел 11.7 сравнивает nikpak 1.2.0 с RAR, 7-Zip и ZIP на одной машине.
11.1 Методика
Пункт
Деталь
Машина
Виртуальная машина Linux x86-64, одно ядро ЦП. Все времена — секунды реального времени на этом одном ядре; многоядерные машины быстрее для обоих инструментов.
Программное обеспечение
RAR 7.00 (26 фев 2024, пробная сборка Linux, формат -ma5); nikpak 1.1.0, собранный в режиме release с LTO; FLAC 1.x -8 как аудио-эталон.
Настройки RAR
-m3 (по умолчанию RAR) и -m5 (лучший). Для теста общих данных также -s (непрерывный) и -md256m (словарь 256 МБ), потому что архивы nikpak всегда непрерывные, и для честного сравнения RAR должен иметь то же самое.
Проверка
Каждый архив nikpak извлекался и сравнивался с оригиналом (cmp для медиафайлов, SHA-256 всех 10 949 файлов для общего набора).
Тестовый материал
Набор
Содержимое
Галерейные WAV
35 звуковых файлов из галереи LibreOffice: моно 16 бит, 23 на 11 025 Гц и 12 на 22 050 Гц. Они содержат лишь около тысячи различных значений сэмплов (компандированные источники) и являются намеренно неудобным случаем для предсказательного кодирования.
Музыка
100-секундная многоинструментальная пьеса (фортепиано, струнные, бас, флейта, ударные), отрендеренная с TiMidity++ и набором звуков Freepats в 44,1 кГц стерео 16 бит (17,4 МБ). SoX создал версии 22,05 кГц моно 16 бит, 22,05 кГц моно 8 бит и 48 кГц стерео 24 бита.
MOD
16 модулей ProTracker из тестовой коллекции libxmp.
BMP
6 изображений: пять фотографий из набора образцов scikit-image (24 бита, плюс 8-битное преобразование одной в оттенки серого) и текстура из TeX Live.
Общие данные
197,6 МБ в 10 949 файлах: стандартная библиотека Python и пакеты, документация и заголовки C с тестовой машины, символические ссылки удалены.
Ограничения этого тестового материала Музыка синтетическая: она отрендерена из MIDI и содержит повторяющиеся отрывки, что помогает всем инструментам на базе LZ, включая этап Zstandard после NAC. Реальные записи содержат меньше точных повторов, так что абсолютные размеры будут отличаться. Сравнение относится ко всем инструментам одинаково, и результат FLAC на том же файле подтверждает, что сам аудиокодек конкурентоспособен, но читатели со специфичным материалом должны измерить его сами: nikpak mt делает именно это.
11.2 Медиафайлы
Набор
Оригинал
RAR 7 -m5
nikpak -m2
nikpak -m5
m5 против RAR
6 фотографий BMP
9,183,956
2,862,744
2,035,223
1,750,706
на 38,8 % меньше
16 файлов ProTracker MOD
2,507,557
1,070,290
966,622
927,973
на 13,3 % меньше
35 галерейных WAV (моно 16 бит)
2,991,820
1,605,879
1,529,219
1,418,532
на 11,7 % меньше
Музыка 44,1 кГц стерео 16 бит
17,371,848
11,024,411
9,415,519
9,411,898
на 14,6 % меньше
Музыка 22,05 кГц моно 16 бит
4,342,996
3,112,135
2,635,819
2,634,669
на 15,3 % меньше
Музыка 22,05 кГц моно 8 бит
2,171,520
844,160
742,462
740,751
на 12,2 % меньше
Музыка 48 кГц стерео 24 бита
28,362,206
21,467,283
(-m3)
18,689,529
18,688,030
на 12,9 % меньше
Все размеры указаны в байтах. Для 24-битного файла RAR измерялся только на -m3, так что эта строка — более слабое сравнение, чем остальные.Рисунок 3: размер архива в процентах от исходных данных (меньше — лучше).Рисунок 4: уменьшение размера nikpak по сравнению с RAR 7.00 -m5.
Что дают медиа-фильтры
Тот же nikpak без медиа-фильтров (версия 1.0, обычный Zstandard на уровне по умолчанию) — правильная мера ценности медиа-слоя:
Набор
nikpak 1.0 (без фильтров)
nikpak 1.1 -m2
Уменьшение
6 фотографий BMP
3,580,971
2,035,223
43.2
%
16 файлов ProTracker MOD
1,260,607
966,622
23.3
%
35 галерейных WAV (моно 16 бит)
1,876,722
1,529,219
18.5
%
Музыка 44,1 кГц стерео 16 бит
15,585,422
9,415,519
39.6
%
Музыка 22,05 кГц моно 16 бит
3,887,183
2,635,819
32.2
%
Музыка 22,05 кГц моно 8 бит
1,078,493
742,462
31.2
%
Сравнение с FLAC
Для стереомузыки 44,1 кГц FLAC -8, специализированный эталонный кодировщик, выдаёт 9 407 019 байтов. Поток NAC для того же аудио — 9 425 305 байтов, в пределах 0,2 %, а готовый архив nikpak — 9 415 519 байтов. Для 22 кГц моно- и 8-битных версий NAC меньше, чем FLAC (2 635 446 против 2 638 954 и 785 890 против 798 810 только для аудиообласти), а для 24 бит архив (18,69 МБ) меньше 19,12 МБ у FLAC. FLAC гораздо слабее на галерейных файлах (2,50 МБ против 1,61 МБ у RAR) по причине, объяснённой в разделе 7.5; это тот случай, в котором другие фильтры заслуживают своё место.
11.3 Общие данные
Исходный код и документы — не медиа, так что этот тест проверяет, не стоят ли nikpak его выигрыши в другом месте чего-либо на обычных файлах.
Инструмент и уровень
Размер (байты)
Время
Извлечение
nikpak -m5
24,443,483
45.6
s
1.8
s
RAR 7 -m5 -s -md256m
25,862,475
36.2
s
RAR 7 -m5 -s
26,002,812
26.7
s
RAR 7 -m3 -s
26,536,863
16.7
s
1.5
s
nikpak -m4
26,814,023
13.5
s
nikpak -m3
30,329,965
2.0
s
nikpak -m2 (по умолчанию 1.1)
36,266,743
0.9
s
0.8
s
RAR 7 -m5 (по умолчанию, не непрерывный)
50,851,230
14.8
s
RAR 7 -m3 (по умолчанию, не непрерывный)
50,974,773
9.7
s
2.3
s
Рисунок 5: общие данные, размер и время создания на одном ядре.Читая таблицу честно:
Максимальный уровень: nikpak создаёт архив на 5,5 % меньше лучшего у RAR (24,4 против 25,9 МБ). RAR быстрее на этом уровне (26,7–36,2 с против 45,6 с).
Равный размер:nikpak -m4 в пределах примерно 1 % от непрерывного уровня по умолчанию у RAR за 81 % времени (13,5 с против 16,7 с).
Быстрые уровни:-m2 меняет степень сжатия на скорость: в 18 раз быстрее непрерывного -m3 у RAR и на 37 % больше. Это уровень для резервных копий и конвейеров, где время важнее последних нескольких мегабайтов.
Не непрерывный: не-непрерывные архивы RAR по умолчанию почти вдвое больше его непрерывных на этих данных со множеством мелких файлов. Любой, кто сравнивает nikpak с RAR, должен добавить -s к RAR.
11.4 Скорость на одном большом медиафайле
Рисунок 6: создание архива из 17 МБ стерео WAV.
Операция
nikpak
RAR 7
Размер
Создание, быстрое / RAR по умолчанию
1.45
s
(-m2)
2.54
s (-m3)
9 415 519 против 11 128 595
Создание, максимальный уровень
3.14
s
(-m5)
5.87
s (-m5)
9 411 898 против 11 024 411
Извлечение
0.28
s
0.23
s
одинаковый вывод
На медиа nikpak и меньше, и быстрее при создании. RAR извлекает чуть быстрее; вероятная причина в том, что декодирование NAC выполняет целочисленное предсказание для каждого сэмпла, что стоит несколько больше, чем копирование совпадений, доминирующее в обычном декодировании.
11.5 Накладные расходы шифрования
На наборе данных 222 МБ зашифрованный архив занял 0,92 с против 0,64 с без шифрования и был на 11 087 байтов (0,03 %) больше. Разница включает вывод Argon2id, так что цена определяется фиксированной долей секунды.
11.6 Воспроизведение результатов
# media: which filter wins, per file
nikpak mt song.wav tracker.mod photo.bmp
# archive with nikpak and RAR, then compare
nikpak a -q -ep -m2 test.nik *.wav
rar a -ep -m5 -ma5 test.rar *.wav
# fair comparison on many files: give RAR solid mode
rar a -r -s -m5 -ma5 -md256m data.rar data
nikpak a -m5 data.nik data
# verify
nikpak x -o+ test.nik restore\
11.7 Второй прогон: nikpak, RAR 7, 7-Zip и ZIP
Обновлено для nikpak 1.2.0. В первой версии этого прогона, с nikpak 1.1.0, 7-Zip -mx9 был впереди на тексте (на 1,4 %), офисных файлах (3,3 %) и исходном коде (8,5 %). nikpak 1.2.0 добавляет пересжатие Deflate (7.9) и новый максимальный уровень, построенный на LZMA2 и PPMd (6.7), и был измерен заново на той же машине с теми же файлами. Цифры для RAR, 7-Zip и ZIP взяты из первого прогона.Разделы 11.2–11.5 сравнивают nikpak только с RAR. Этот второй прогон добавляет два архиватора, которые уже есть у большинства людей, — 7-Zip и классический формат ZIP, и два вида файлов, которые архивируются каждый день: обычный текст и офисные документы (.doc, .docx, .xls, .xlsx, .csv, .pdf). Все четыре инструмента запускались один за другим на одной машине и одних и тех же файлах, а RAR был измерен заново. Корпуса были пересобраны из тех же публичных источников, так что абсолютные размеры и времена отличаются от разделов 11.2–11.4. Сравнивайте числа внутри этого раздела, а не между разделами.
Метод
Пункт
Деталь
Машина
Виртуальная машина Linux x86-64 (Intel Xeon, 2,8 ГГц). Каждая команда привязывалась к одному ядру ЦП через taskset и запускалась однопоточно (nikpak -mt1, RAR -mt1, 7-Zip -mmt=1; ZIP однопоточный по своей конструкции).
Программное обеспечение
nikpak 1.2.0 (сборка release); RAR 7.00 (-ma5, непрерывный); 7-Zip 23.01 (формат .7z, LZMA2, непрерывный по умолчанию); Info-ZIP Zip 3.0 и UnZip 6.0 (Deflate).
Уровни
nikpak: быстрый уровень -m2 и максимальный -m5, который по умолчанию с 1.2.1 (и -m4). Остальные: по умолчанию и максимальный, RAR -m3 -s / -m5 -s, 7-Zip -mx5 / -mx9, ZIP -6 / -9. RAR был дан непрерывный режим (-s), потому что остальные три непрерывные или, в случае ZIP, не могут быть такими.
Хронометраж
Секунды реального времени. Наборы меньше 50 МБ: лучший из трёх прогонов. Общий набор: один прогон.
Проверка
Все 92 архива были извлечены и сравнены с оригиналом с помощью diff -r. Все оказались идентичными.
Тестовый материал
Набор
Файлы
Размер (байты)
Содержимое
Изображения BMP
8
6,987,840
Шесть фотографий из набора образцов scikit-image в виде 24-битных BMP, плюс 8-битная фотография в оттенках серого и 8-битная текстура гравия.
ProTracker MOD
16
2,252,604
16 самых больших модулей ProTracker в тестовой коллекции libxmp.
Галерейные WAV
35
2,991,820
Те же 35 звуков галереи LibreOffice, что и в 11.1.
Музыка, четыре формата
4
× 1
53,417,226
Новая 100-секундная пьеса (фортепиано, струнные, бас, флейта, ударные), отрендеренная с TiMidity++ и Freepats в 44,1 кГц стерео 16 бит, затем преобразованная SoX в 22,05 кГц моно 16 бит и 8 бит и в 48 кГц стерео 24 бита.
Обычный текст
18
11,793,318
Восемнадцать книг проекта «Гутенберг» в формате .txt (Остин, Мелвилл, Шекспир, Библия короля Иакова и другие).
Офисные файлы
60
39,100,915
12 отчётов в .docx, .doc и .pdf (текст, заголовки, таблицы и немного фотографий) и 8 книг продаж от 500 до 30 000 строк в .xlsx, .xls и .csv (с формулами), сохранённых LibreOffice.
Общие данные
11,473
190,454,632
Стандартные библиотеки Python 3.12 и 3.13, пакеты Python из Debian, заголовки C (/usr/include) и /usr/share/doc. Символические ссылки удалены.
Максимальные уровни: размер архива
Набор
Оригинал
nikpak -m5
RAR 7 -m5
7-Zip -mx9
ZIP -9
8 изображений BMP
6,987,840
3,557,350
4,394,310
4,195,043
4,974,680
16 файлов ProTracker MOD
2,252,604
1,127,607
1,264,245
1,166,855
1,408,085
35 галерейных WAV (моно 16 бит)
2,991,820
1,346,484
1,596,971
1,484,879
1,852,279
Музыка 44,1 кГц стерео 16 бит
17,760,408
8,731,989
10,460,042
10,666,922
15,225,764
Музыка 22,05 кГц моно 16 бит
4,440,136
2,458,867
2,797,026
2,784,080
3,736,722
Музыка 22,05 кГц моно 8 бит
2,220,090
606,840
725,416
642,341
836,989
Музыка 48 кГц стерео 24 бита
28,996,592
18,198,056
21,229,465
25,542,036
26,980,770
18 книг обычного текста (.txt)
11,793,318
2,741,898
3,519,622
3,259,868
4,223,579
60 офисных файлов
39,100,915
6,887,729
11,186,217
10,085,779
17,399,998
Общие данные (11 473 файла)
190,454,632
28,175,618
33,606,893
28,879,398
62,198,510
Все размеры указаны в байтах. Самый маленький архив в каждой строке показан жирным.Рисунок 7: размер архива на максимальном уровне каждого инструмента в процентах от оригинала (меньше — лучше).
Быстрые уровни: размер и время создания
Набор
nikpak -m2
RAR 7 -m3
7-Zip -mx5
ZIP -6
8 изображений BMP
54.0
% · 0.39 s
63.0
% · 2.09 s
60.1
% · 3.51 s
71.2
% · 0.35 s
16 файлов ProTracker MOD
52.4
% · 0.61 s
56.2
% · 0.43 s
51.9
% · 0.69 s
62.7
% · 0.10 s
35 галерейных WAV (моно 16 бит)
51.1
% · 0.41 s
53.6
% · 0.71 s
49.6
% · 1.96 s
61.9
% · 0.24 s
Музыка 44,1 кГц стерео 16 бит
49.2
% · 1.72 s
59.9
% · 3.60 s
60.1
% · 14.03 s
85.7
% · 0.82 s
Музыка 22,05 кГц моно 16 бит
55.4
% · 0.58 s
64.1
% · 0.95 s
62.7
% · 2.14 s
84.2
% · 0.22 s
Музыка 22,05 кГц моно 8 бит
27.4
% · 0.77 s
33.3
% · 0.52 s
28.9
% · 2.13 s
38.2
% · 0.32 s
Музыка 48 кГц стерео 24 бита
62.8
% · 2.06 s
73.6
% · 7.54 s
88.1
% · 13.54 s
93.0
% · 1.19 s
18 книг обычного текста (.txt)
35.2
% · 0.11 s
30.4
% · 5.53 s
27.7
% · 11.76 s
36.0
% · 0.89 s
60 офисных файлов
38.0
% · 0.22 s
29.5
% · 8.25 s
26.2
% · 21.85 s
44.7
% · 1.83 s
Общие данные (11 473 файла)
25.3
% · 1.67 s
18.0
% · 48.19 s
17.0
% · 93.71 s
32.9
% · 7.32 s
nikpak -m2 против уровня по умолчанию других инструментов. Каждая ячейка показывает размер архива в процентах от оригинала и время создания на одном ядре. Самый маленький архив в каждой строке — жирным.
Общие данные подробно
Инструмент и уровень
Размер (байты)
% от оригинала
Создание
Извлечение
nikpak -m5
28,175,618
14.8
%
154.3
s
5.6
s
7-Zip -mx9
28,879,398
15.2
%
120.9
s
6.0
s
RAR 7 -m5 -s -md256m
32,350,575
17.0
%
73.6
s
7.0
s
7-Zip -mx5
32,375,802
17.0
%
93.7
s
4.5
s
nikpak -m4
33,295,133
17.5
%
37.8
s
3.3
s
RAR 7 -m5 -s
33,606,893
17.6
%
72.4
s
6.7
s
RAR 7 -m3 -s
34,236,198
18.0
%
48.2
s
5.9
s
nikpak -m2
48,229,284
25.3
%
1.7
s
0.9
s
RAR 7 -m3 (не непрерывный)
56,038,351
29.4
%
20.2
s
6.9
s
ZIP -9
62,198,510
32.7
%
28.2
s
6.9
s
ZIP -6
62,672,415
32.9
%
7.3
s
5.4
s
Рисунок 8: общие данные, размер и время создания всех четырёх инструментов на одном ядре.
От 1.1.0 к 1.2.0
Набор
nikpak 1.1.0 -m5
nikpak 1.2.0 -m5
7-Zip -mx9
1.2.0 против 7-Zip
18 книг обычного текста
3,306,819
2,741,898
3,259,868
на 15,9 % меньше
60 офисных файлов
10,417,750
6,887,729
10,085,779
на 31,7 % меньше
Общие данные
31,322,041
28,175,618
28,879,398
на 2,4 % меньше
Читая результаты честно
nikpak -m5 наименьший на каждом наборе. Против 7-Zip -mx9 он на 2,4–31,7 % меньше, против RAR 7 -m5 — на 10,8–38,4 %, а против ZIP -9 — на 19,9–60,4 %. На записанном аудио NAC предсказывает то, что LZ-компрессоры могут лишь совмещать: на 24-битной музыке 7-Zip экономит 12 %, а nikpak — 37 %.
Офисные файлы: на 31,7 % меньше, чем у 7-Zip. Пересжатие Deflate превращает 6,6 МБ .xlsx и 1,9 МБ .docx в открытый XML, который LZMA2 сжимает гораздо лучше, чем это делал Deflate (6,89 МБ против 10,09 МБ). Даже -m4 на 1,3 % меньше, чем 7-Zip -mx9, и быстрее (16 с против 26 с). Цена на -m5 — время: 81 с против 26 с.
Текст: на 15,9 % меньше, за половину времени. PPMd выигрывает на прозе (6,4 с против 12,9 с на создание). Поскольку PPMd декодирует так же медленно, как кодирует, извлечение занимает 2,7 с вместо 0,2 с.
Исходный код: на 2,4 % меньше, узкое преимущество. 28,2 МБ против 28,9 МБ, за 154 с против 121 с. Сортировка по типу файла и выбор движка на непрерывных выборках (6.7) дали разницу.
Быстрый уровень -m2: самый быстрый, не самый маленький. nikpak -m2 требуется 1,7 с для общего набора, против 93,7 с у 7-Zip -mx5 (в 56 раз дольше), 48,2 с у RAR и 7,3 с у ZIP. Он меньше 7-Zip -mx5 на изображениях и на большей части аудио (файлы MOD и галерейные WAV на 1–3 % больше), но больше на тексте, офисных файлах и исходном коде (49,0 % на общем наборе). Поэтому с версии 1.2.1 nikpak по умолчанию использует -m5; -m2 нужно запрашивать явно.
ZIP быстрый, но самый большой везде. Даже nikpak -m2 превосходит ZIP -9 на каждом наборе. ZIP создаёт маленькие медиа-архивы быстрее, чем nikpak -m2, потому что Deflate делает гораздо меньше работы, чем кодек NAC, но он медленнее на тексте, офисных файлах и исходном коде.
Извлечение. Общий набор извлекается за 0,9 с (nikpak -m2) или 5,6 с (-m5), против 6,0 с у 7-Zip, 6,7 с у RAR и 6,9 с у ZIP. Архивы с пересжатыми потоками Deflate извлекаются медленнее, потому что каждый поток перестраивается (2,1 с против 0,7 с для офисного набора).
RAR на этой машине. RAR был здесь медленнее, чем в 11.3 (72 с вместо 27 с для -m5 -s на похожем объёме исходного кода). Машина и данные отличаются, так что два раздела не следует смешивать. В рамках этого прогона каждый инструмент находился в одинаковых условиях.
Что это значит для nikpak
На максимальном уровне nikpak 1.2.0 создаёт наименьший архив из всех четырёх инструментов на каждом измеренном наборе, на 2,4–31,7 % меньше, чем 7-Zip -mx9. Цена — скорость: -m5 однопоточный и медленнее 7-Zip на офисных файлах и исходном коде. Ускорение есть в планах (раздел 15.2).
12 nikpak и RAR в сравнении
RAR — отличный и широко используемый архиватор, и эта глава не притворяется обратным. Она излагает, где измерения и проектирование в пользу nikpak, где впереди RAR и кому что выбирать.
12.1 Где nikpak впереди
Область
nikpak
Свидетельство
Аудио, изображения, трекерная музыка
на 12–39 % меньше, чем RAR 7 -m5, на каждом измеренном медиа-наборе
Раздел 11.2
Исходный код, максимальный уровень
на 5,5 % меньше лучшей непрерывной настройки RAR
Раздел 11.3
Скорость на быстром уровне -m2
0,9 с против 9,7–16,7 с для 197 МБ; 1,45 с против 2,54 с для WAV
Разделы 11.3, 11.4
Шифр и режим
XChaCha20-Poly1305, аутентифицированное; RAR5 использует AES-256 в режиме CBC, который не аутентифицирован и полагается на отдельные контрольные суммы
Глава 8
Хеширование пароля
Argon2id, ресурсоёмкий по памяти (64 МиБ); RAR5 использует PBKDF2-HMAC-SHA256, который ограничен ЦП и дёшево распараллеливается на GPU
Раздел 8.2
Приватность имён файлов
Всегда зашифрованы; RAR нужен ключ -hp
Раздел 8.4
Генерация пароля
Встроена: стойкий случайный пароль, когда не указан другой
Раздел 3.3
Обнаружение подделки
Перестановка, усечение и изменения заголовка обнаруживаются криптографически
Раздел 8.6
Прозрачность
Полный исходный код и документированный формат; реализация на Rust с безопасной памятью
Главы 5, 10
Распространение
Один статический исполняемый файл (окно перетаскивания и командная строка; около 2,3 МБ без окна) или небольшой установщик Windows; условно-бесплатное ПО, бесплатно для личного использования (3.8)
Глава 13
12.2 Где RAR впереди
Область
RAR 7
nikpak сегодня
Записи восстановления
Могут чинить повреждённые архивы
Обнаруживает повреждение, но не может его починить
Многотомные архивы
Да
Нет
Самораспаковывающиеся архивы
Да
Нет
Обновление архива
Добавление, замена и удаление файлов на месте
Только создание или перезапись
Графический интерфейс
WinRAR, с интеграцией с оболочкой
Окно перетаскивания для сжатия (3.7); нет интеграции с оболочкой, извлечение из командной строки
Новый; нет независимого аудита; читает только .nik
12.3 Квантовая стойкость в перспективе
И nikpak, и RAR5 шифруют 256-битным симметричным ключом, так что оба не затронуты алгоритмом Шора и оба сохраняют около 128 бит безопасности против алгоритма Гровера. Ни одно из этих утверждений их не различает. Сверху nikpak добавляет ресурсоёмкий по памяти шаг пароля (который делает доминирующую реальную атаку — подбор пароля — гораздо дороже) и аутентифицированное шифрование (которое делает подделку обнаружимой). Он также с самого начала спроектирован в предположении, что никакой примитив с открытым ключом никогда не станет частью формата архива, а его план развития обязуется использовать гибридную постквантовую схему, если будет добавлен обмен открытыми ключами.
12.4 Что выбрать
Выбирайте nikpak для архивов аудио, изображений, трекерной музыки и исходного кода, где важны размер и скорость, для автоматизированных резервных копий, для стойкого шифрования по умолчанию и когда ценен открытый, документированный формат.
Выбирайте RAR, когда нужны записи восстановления, многотомные или самораспаковывающиеся архивы, обновление на месте или обмен архивами с людьми, у которых есть только инструменты RAR.
Используйте оба: ничто не мешает рабочему процессу использовать nikpak для массового медиа и зашифрованных резервных копий, сохраняя RAR для распространения.
12.5 А 7-Zip и ZIP?
Раздел 11.7 измеряет nikpak 1.2 также против 7-Zip 23.01 и Info-ZIP 3.0. Вкратце:
Выбирайте nikpak -m5 для самого маленького архива. Он на 2,4–31,7 % меньше, чем 7-Zip -mx9, на каждом измеренном наборе: на 31,7 % на офисных файлах, на 15,9 % на тексте и на 2,4 % на исходном коде. Выбирайте nikpak -m2 для быстрых резервных копий (в 56 раз быстрее 7-Zip по умолчанию на исходном коде). У nikpak также более стойкое шифрование: 7-Zip использует AES-256 с получением ключа SHA-256, которое не ресурсоёмко по памяти, и скрывает имена файлов только с -mhe.
Выбирайте 7-Zip, когда на максимальном уровне важнее время (он быстрее на больших офисных и исходных наборах), когда нужно, чтобы его уровень по умолчанию был мал на документах, или когда нужно открывать множество форматов, которые читает 7-Zip.
Выбирайте ZIP только ради совместимости. Любая операционная система открывает его без дополнительного ПО, но nikpak -m5 на 19,9–60,4 % меньше, а традиционное шифрование ZIP слабое.
13 Сборка, развёртывание и интеграция
13.1 Windows с PowerShell
nikpak написан на Rust и собирается с помощью Cargo. На Windows Rust нужен компоновщик C/C++, который поставляется с Visual Studio Build Tools. В PowerShell администратора установите оба один раз и затем снова откройте PowerShell:
Если winget недоступен, установите Rust с rustup.rs и Build Tools for Visual Studio с рабочей нагрузкой Desktop development with C++. Затем в папке с исходниками:
.\build.ps1 # builds dist\nikpak.exe and dist\unNik.exe
build.ps1 проверяет, что Cargo установлен (и объясняет, как его установить, если нет), запускает сборку, объясняет обычную причину при неудаче и копирует исполняемый файл в dist\nikpak.exe.
Установщик Windows
.\build.ps1 -Installer (или npm run installer) также собирает программу установки dist\nikpak--setup.exe с помощью Inno Setup 6.3 или новее (установите его один раз командой winget install JRSoftware.InnoSetup). Сценарий — installer\nikpak.iss; версия берётся из Cargo.toml. Этот файл установки и загружается на сайты shareware и загрузок.
По умолчанию он устанавливается только для текущего пользователя, без прав администратора и запроса UAC, в %LOCALAPPDATA%\Programs\NikPak. Его первая страница предлагает «установить для всех пользователей» (Program Files, требуются права администратора).
Он показывает LICENSE.txt для принятия и устанавливает nikpak.exe, unNik.exe, значки, LICENSE.txt, THIRD-PARTY-NOTICES.txt и CHANGELOG.md. Он добавляет пункт в меню «Пуск», необязательный значок на рабочем столе и, по запросу, папку в PATH для командной строки. Он регистрирует программу удаления в Параметры > Приложения.
Ярлыки: NikPak, unNik и лицензия в меню «Пуск»; NikPak на рабочем столе (всегда) и unNik на рабочем столе как опция.
Файлы .nik всегда регистрируются (с 1.5.2): они получают собственный значок (nikfile.ico, страница с застёжкой-молнией, как у файлов .zip), имя типа «Архив NikPak», и двойной щелчок открывает их в unNik («Открыть с помощью unNik» в контекстном меню). unNik также указан в «Открыть с помощью» и в Приложения по умолчанию. Программа удаления снимает регистрацию. Если файлы .nik уже были настроены на открытие другой программой, Windows сохраняет этот выбор, пока unNik не будет выбран один раз в «Открыть с помощью».
Завершающий «Запустить NikPak» запускает NikPak как обычный пользователь, никогда как администратор, так что перетаскивание работает. Обновления устанавливаются поверх предыдущей версии (фиксированный AppId). Лицензия в %APPDATA%\nikpak сохраняется при обновлении и удалении. Установщик никогда не содержит ключей или файлов ключей.
Установщик работает на английском или французском, следуя Windows. Перед публикацией подпишите nikpak.exe и установщик сертификатом подписи кода, чтобы Windows SmartScreen не предупреждал о неизвестном издателе.
buildall.ps1 собирает всё, что публикуется, за один запуск — nikpak.exe, unNik.exe, два установщика и SHA256SUMS.txt — копирует их в binaries\, пересобирает веб-сайт и загружает его по FTP (-NoUpload пропускает загрузку). Второй установщик, unnik--setup.exe (installer\unnik.iss), устанавливает только unNik, бесплатный просмотрщик архивов; когда NikPak уже установлен, он устанавливает только программу, так что меню никогда не дублируются.
13.2 Сборка с npm
Проекты Rust не используют npm, поэтому npm никогда не требуется. Для удобства проект содержит небольшой package.json, чьи сценарии просто вызывают Cargo, так что разработчик, живущий в рабочем процессе Node.js, может набирать знакомые команды:
npm run build # cargo build --release
npm run dist # build.ps1 -> dist\nikpak.exe
npm test # cargo test --release
npm run clean # cargo clean
13.3 Самодостаточный исполняемый файл
Файл .cargo/config.toml связывает среду выполнения C статически для целей Windows MSVC. Получившийся nikpak.exe (несколько МБ с графическим интерфейсом, около 2,3 МБ без него) поэтому не имеет зависимостей от DLL и не требует Visual C++ Redistributable на машинах, где он работает. Скопируйте его в папку в PATH, чтобы использовать где угодно. Профиль release включает полную оптимизацию, оптимизацию времени компоновки, одну единицу генерации кода, удаление символов и panic = abort для маленького и быстрого двоичного файла.
13.4 macOS и Linux
./build.sh # builds and copies the result to dist/nikpak
# or: cargo build --release
sudo cp dist/nikpak /usr/local/bin/
На macOS сначала установите инструменты командной строки (xcode-select --install); на Debian или Ubuntu установите компилятор C (sudo apt install build-essential). Сам Rust ставится командой curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh. Библиотека сжатия компилируется Cargo из её C-исходников, так что системная библиотека не нужна.Загрузки сайта для macOS и Linux создаются сценарием ./package-unix.sh, который собирает nikpak и unNik и упаковывает их с install.sh в binaries\nikpak--macos.zip (универсальный двоичный файл: Intel + Apple silicon) или binaries\nikpak--linux-.tar.gz. Установите ZIG=1 на Linux, чтобы собирать с cargo-zigbuild против glibc 2.28, так что программы будут работать и на старых дистрибутивах.
13.5 Зависимости
С версии 1.2 nikpak требуется Rust 1.89 или новее. build.ps1 и build.sh проверяют установленную версию и выполняют rustup update stable, если она старше. С npm один раз выполните rustup update перед npm run build.nikpak зависит от небольшого набора зрелых крейтов. Их точные версии зафиксированы в Cargo.lock, который входит в пакет исходников, так что каждая сборка использует один и тот же код.
Крейт
Назначение
zstd
Сжатие Zstandard, с многопоточностью
chacha20poly1305
XChaCha20-Poly1305 и конструкция STREAM (RustCrypto)
argon2
Получение ключа Argon2id (RustCrypto)
rand
Доступ к безопасному генератору случайных чисел операционной системы
zeroize
Стирание ключей и паролей из памяти
rpassword
Чтение пароля без вывода на экран, на каждой платформе
crc32fast
Быстрый CRC32
glob
Раскрытие подстановочных знаков (PowerShell не раскрывает подстановочные знаки для нативных программ)
liblzma
Движок LZMA2 для -m5 (liblzma, компилируется статически из C-исходников)
ppmd-rust
Движок PPMd вариант I для текста на -m5
preflate-rs
Побитно точное пересжатие Deflate (Microsoft, Apache-2.0); встроенная копия в vendor/preflate-rs, чей LGPL-энтропийный кодер (cabac) заменён собственным диапазонным кодером nikpak, так что nikpak не содержит кода LGPL. Требует Rust 1.89 или новее
eframe / egui
Графический интерфейс (необязательная функция cargo gui, включена по умолчанию)
Шейпинг и упорядочение справа налево для хинди, бенгали и арабского в окне (необязательная функция cargo gui)
13.6 Сценарии
Предсказуемые коды выхода и пароль через переменную окружения делают nikpak удобным для сценариев. Резервная копия в PowerShell, которая считает предупреждения приемлемыми, а всё худшее — неудачей:
Интеграция, описанная в разделе 3.6, опирается на то, что nikpak следует синтаксису RAR. Краткий чек-лист: зарегистрируйте расширение nik; используйте a для упаковки и x для распаковки; позвольте оболочке передавать @listfile для длинных списков файлов; дайте -o+ или -y для автоматического извлечения; и передавайте пароль через -p или переменную NIKPAK_PASSWORD, поскольку у графической оболочки нет консоли для запроса.
14 Тестирование и проверка
Поскольку архиватор хранит данные людей, nikpak тестируется на четырёх уровнях.
14.1 Модульные тесты
Тридцать четыре автоматических теста выполняются командой cargo test --release:
Область
Что проверяется
Поток шифрования
Круговые проходы на 0, 1, 100, 65 535, 65 536, 65 537, 131 072, 131 077 и 327 803 байтах (вокруг границ фрагментов 64 КиБ); неверный заголовок (связанные данные), неверный ключ и усечение должны терпеть неудачу.
Круговой проход без потерь для 8/16/24/32-битного аудио, 1, 2, 3 и 6 каналов, девяти типов сигнала (тишина, шумная синусоида, белый шум, прямоугольная волна полной шкалы, пила, одиночный импульс, постоянный максимум, потерянные младшие биты, постоянный минимум), восьми длин блока от 1 до 5000 сэмплов, трёх уровней усилий и принудительного дословного кодирования.
Аудиометоды
NAC, Shuffle и Shuffle+Delta на всех разрядностях, числах каналов, порядках байтов и знаковостях, включая блоки, которые не делятся нацело.
Определение и файлы
WAV (моно, стерео, 8/16/24/32 бита, расширяемый, шесть каналов, завершающие фрагменты, нечётные остаточные байты, нулевая и завышенная длина данных), AIFF, MOD (также усечённые) и BMP (8/24/32 бита, дополнение строк, завершающие данные); WAV с плавающей точкой, крошечные файлы и текст не должны определяться; каждый файл проходит круговой проход через каждый применимый фильтр.
Устойчивость
Тысячи случайных и перевёрнутых по битам блоков, поданных аудиодекодеру и медиадекодеру: они должны возвращать ошибки, никогда не паниковать и не исчерпывать память.
Кадрирование и вспомогательные функции
Кадрирование фрагментов с завершающими данными, очистка путей, сопоставление подстановочных знаков и фильтров, форматирование дат, генерация пароля.
Пересжатие Deflate
Контейнеры ZIP на уровнях Deflate 1, 3, 6 и 9, PDF с двумя потоками zlib, gzip с тремя членами, не-контейнеры; 400 повреждённых или усечённых пересжатых потоков должны завершаться чистой ошибкой (паники preflate перехватываются).
Много-движковые блоки
Круговые проходы через блоки zstd, LZMA2 и PPMd вокруг границы кадра 256 КиБ; 300 повреждённых или усечённых тел; враждебные параметры движка; проба PPMd/LZMA2.
Графический интерфейс
Запуск на виртуальном дисплее (Xvfb): экраны простоя, наведения, прогресса и завершения проверяются визуально; брошенная папка архивируется и извлекается байт в байт; Отмена и закрытие во время сжатия не оставляют файлов; без дисплея происходит откат к тексту справки.
Лицензия
Ключи, созданные nikpak-keygen и PHP-комплектом, идентичны и принимаются; изменённые имя, электронная почта, тип или ключ и ключи, подписанные другим ключом, отклоняются. На виртуальном дисплее: напоминание в обоих порядках кнопок, ошибка неверного ключа, успешная регистрация, перезапуск без напоминания; текст остаётся внутри рамок.
Языки
Каждый язык переводит каждый текст с теми же плейсхолдерами; гласные знаки деванагари и соединения арабского проходят шейпинг; на виртуальном дисплее все десять языков проверялись экран за экраном (напоминание, простой, прогресс, готово, «О программе», регистрация, меню языков); выбор языка сохраняется, и nikpak перезапускается на нём.
API архива
Чтение индекса, извлечение одного файла из папки (он попадает без пути папки), удаление папки с её содержимым и удаление всего — для -m5, zstd + шифрование и архивов без сжатия; неверный пароль сообщается как таковой.
Просмотрщик архивов
Построение дерева с подразумеваемыми папками, определение и декодирование текста (UTF-8, UTF-16, Windows-1252), перенос строк и поиск в просмотрщике. На виртуальном дисплее: открытие, пароль, навигация, выбор, поиск, просмотрщик, извлечение, удаление и тест на нескольких языках.
Скины и меню файлового менеджера
Файлы меню Linux генерируются и проверяются; один архив для выбора, запущенный как три программы; --add-here с тремя элементами и --extract-here / --extract-to под виртуальным дисплеем; зашифрованные архивы запрашивают свой пароль и извлекают идентичные файлы; каждый новый текст интерфейса переведён на десять языков (утверждение «каждый язык переводит каждый текст»).
14.2 Сквозные тесты
Каждый бенчмарк-архив извлекался и сравнивался со своим источником байт в байт (SHA-256 для набора из 10 949 файлов) на нескольких уровнях.
Смешанный архив (WAV, MOD, BMP, текст, случайные данные, подпапки) создавался, выводился списком, тестировался, полностью извлекался, и один файл извлекался из его середины.
Тот же архив создавался с шифрованием, тестировался с верным и неверным паролем и извлекался.
Архивы, записанные предыдущей версией формата (1.0), открывались версией 1.1.
Интерактивный ввод пароля проверялся через псевдотерминал: совпадающие пароли, несовпадение, пустой ввод (генерация), верные и неверные пароли при открытии.
14.3 Атаки-тесты
Подделка, усечение, перестановка фрагментов, манипуляции с заголовком, мусорные файлы и архивы с обходом пути из раздела 10.1 прогонялись против каждого релиз-кандидата. Результаты сведены в таблицы в разделах 8.6 и 10.1; ожидаемый исход в каждом случае — отказ, ясное сообщение и ненулевой код выхода, никогда не паника и никогда не запись за пределы места назначения.
14.4 Дефекты, найденные тестированием
Тестовая кампания — причина того, что несколько дефектов не существуют в выпущенной программе. Два примера: поиск параметра Райса, который не срабатывал для 32-битного аудио и записал бы многогигабайтный код (найден матрицей модульных тестов и исправлен), и сбой контрольной суммы zstd, который сообщался с общим кодом выхода 2 вместо 3 (найден в тестах подделки и исправлен). Третий пример — сама методология бенчмарка: первое сравнение с RAR использовало его не-непрерывный режим по умолчанию, что льстило nikpak на исходном коде; оно было переделано в непрерывном режиме, и результаты в главе 11 — исправленные.
15 Ограничения и план развития
15.1 Текущие ограничения
Ограничение
Подробности и обходной путь
Нет записей восстановления, томов или SFX
Повреждение обнаруживается, а не чинится (храните вторую копию важных архивов); при необходимости разбивайте большие архивы общим инструментом.
Нет обновления на месте
Формат — один непрерывный поток. Удаление (nikpak d или Delete в unNik) перезаписывает архив; добавление файлов в существующий архив не поддерживается: создайте новый архив или перезапишите с -o+.
Последовательный доступ
Извлечение одного файла из очень большого архива читает всё, что ему предшествует (медиа-записи пропускаются без декодирования); unNik прекращает чтение после последнего выбранного файла.
Покрытие медиа
Целочисленные PCM WAV и AIFF, ProTracker MOD, несжатые BMP. Float WAV, ADPCM, XM/S3M/IT и сжатые изображения хранятся с обычным сжатием.
Память на высоких уровнях
Архивы -m4 и -m5 используют окно 128 МиБ; их распаковка требует такого объёма памяти.
Максимальный уровень -m5
Single-threaded and the slowest level. Creating needs up to about 1.1 GB of memory, extracting up to about 350 MB.
Символические ссылки и даты
Ссылки пропускаются при архивировании и отклоняются при извлечении; даты выводятся в UTC.
Проверка безопасности
Не проходила независимого аудита.
Сборки Windows и macOS
Разработано, протестировано и замерено на Linux. Пути кода, специфичные для Windows и macOS, просмотрены вручную, но ещё не проверены на этих системах: запустите там cargo test --release, прежде чем полагаться на сборку.
15.2 План развития
Пункт
Назначение
Записи восстановления
Чётность Рида–Соломона, чтобы повреждённые архивы можно было чинить — главная функция, которой не хватает пользователям RAR.
Многотомные архивы и поддержка обновления
Разбиение больших архивов, добавление и замена файлов.
Обмен открытыми ключами по гибридной схеме
Шифрование архива на ключ получателя с X25519 в сочетании с ML-KEM, безопасное, если устоит любой из компонентов.
Больше медиа-фильтров
Аудио с плавающей точкой, трекеры XM/S3M/IT, пересжатие PNG, двумерный фильтр для TGA и несжатого TIFF.
Чтение ZIP и RAR, интеграция с оболочкой
Распаковка распространённых форматов в unNik и перетаскивание файлов из unNik, так что nikpak может быть единственным установленным инструментом. (Контекстные меню Explorer и Finder появились в 1.5.5, раздел 3.11.)
Более быстрый максимальный уровень
-m5 однопоточный и до трёх раз медленнее 7-Zip -mx9 на офисных файлах: многопоточные блоки LZMA2 и PPMd, дедупликация идентичных файлов и фильтр BCJ для исполняемых файлов.
Внешняя проверка безопасности
Независимый аудит криптографического кода и распаковщика.
память от 8 x дорожек до 1 ГиБ, проходы 1 .. 64, дорожки 1 .. 64
Nonce потока
19-байтовый случайный префикс + 32-битный счётчик + 1-байтовый флаг последнего = 24 байта
Минимальная длина пароля
8 символов
Сгенерированный пароль
24 символа, алфавит из 56 символов, около 139 бит
Минимальный размер медиафайла
8 КиБ (область не менее 4 КиБ)
Блок NAC
4096 кадров сэмплов; блок Shuffle 32768 кадров
Проба
до трёх окон по 768 КиБ (5 %, 45 %, 85 %); вся область, если до 3 МиБ; запас 2 %
Предел области BMP
256 МиБ
Окно Zstandard
по умолчанию; 2^27 с поиском длинных совпадений на -m4 и -m5
Потоки
1 .. 256 (-mt)
B Приложение B: глоссарий
Термин
Значение
AEAD
Аутентифицированное шифрование со связанными данными: шифрует и обнаруживает любые изменения, в том числе данных, передаваемых открыто (например, заголовка).
Argon2id
Ресурсоёмкая по памяти функция хеширования пароля, стандартизированная в RFC 9106; превращает пароль в ключ с намеренно высокой ценой по памяти.
CRC32
32-битная контрольная сумма, обнаруживающая случайные повреждения. Не является функцией безопасности.
Функция, чья цена определяется в основном памятью, что ограничивает ускорение, доступное на GPU и специализированных чипах.
NAC
Аудиокодек без потерь nikpak.
PPMd
Предсказание по частичному совпадению (вариант I): предсказывает каждый байт по предыдущим до 8 байтам; очень силён на тексте.
preflate
Метод (и библиотека), превращающий поток Deflate в его открытые данные плюс небольшие поправки, из которых можно перестроить идентичный поток Deflate.
Кодирование Райса
Простой, быстрый код для чисел с примерно геометрическим распределением: унарное частное и фиксированное число младших битов.
Алгоритм Шора
Квантовый алгоритм, раскладывающий целые числа на множители и вычисляющий дискретные логарифмы, взламывающий RSA и криптографию на эллиптических кривых.
Непрерывный архив
Архив, сжатый как один непрерывный поток, так что можно использовать избыточность между файлами.
STREAM
Конструкция, шифрующая длинное сообщение как аутентифицированные фрагменты со счётчиком и флагом последнего фрагмента в nonce.
Зигзагообразное отображение
Отображение знаковых целых в беззнаковые (0, -1, 1, -2 ... в 0, 1, 2, 3 ...), так что малые величины становятся малыми числами.
Zstandard
Современный открытый формат сжатия, сочетающий сопоставление LZ77 с энтропийным кодированием Хаффмана и FSE.