fgntfg
Snusmumriken
Ну тестовый сурц болтается где-то тут:
https://pastebin.com/fWJCiVBm
https://pastebin.com/sn6sdTVL
fgntfg
Snusmumriken
Хочешь маленькую задачку?
Накатай свой формат для "архива", где типа
[любые данные]
[заголовок с внутренним путём до файла, длина файла]
[тело файла]
[любые данные]
[следующий заголовок]
[следующее тело]
[любые данные]
Чтобы работало на любых размерах файлов. Это весело, ибо нужно учесть кучку мелочей.
А такой свободный формат - чтобы можно было делать rarjpeg'и :)
Ну, или двойной архив, который разными программами открывается по разному.
fgntfg
а старый добрый rarjpeg чем не устаривет?
fgntfg
Видел я дискуссию по этой теме лет 7 назад в /b
Snusmumriken
Ну, тут специфика определённая : )
а) можно ебошить произвольное сжатие (и вообще, свои алгоритмы)
б) конкретно картинка весом в 100мб вызывает подозрение (я хочу паковать ресурсы love-игрулек в zip + данный формат, чтобы важные скрипты были скрыты внутри данного формата, а основные ресурсы - на виду, в zip'е)
Snusmumriken
Правда, я уже сделал подобный парсер/упаковщик, правда без сжатия, хм.
Alexey
zip64 :)
Alexey
там в принципе то что нужно
Snusmumriken
Я не хочу распространённых вариантов, потому что они легко вскрываются.
Свои форматы/своё сжатие/свои ништяки - чтобы сложнее было ломать. Особенно обфусцированное/скомпиленное в бинарь.
Alexey
правда с различными вариациями
Alexey
zip64+AES
fgntfg
[ключ][длина пути][путь][размерность длины данных][длина данных][crc заголовка][данные...][crc данных][общее crc]
Snusmumriken
Смотри какая Самая Главная Проблема защиты lua-ресурсов:
1. Код - интерпретируемый.
2. Все хвосты для расшифровки - на виду (с минификацией/обфускацией - не так на виду, но тоже на виду), ну, типа "опа, он вскрыл этот архив этой функией, давайте её посмотрим или перепишем прогу чтобы всё вскрытое писалось в файлы! Так я распакую вообще всё!".
3. На каждый компилятор найдётся декомпилятор.
Поэтому, остаётся только идти на уловки, чтобы вскрывали о-о-о-о-очень медленно, вроде ручной обфускации видимой части программы, чтобы автоматика не справилась.
fgntfg
Snusmumriken
Ну, если кому-то особо нужно - да, я просто хочу создать сложности для тех, кто будет пытаться читерить в сетевых играх, с игроками-хостами : )
Максимум неочевидности, в общем.
Saphire
Saphire
Snusmumriken
Хитро : )
Придумай.
Сначала тебе надо найти этот самый заголовок.
Как ты будешь прочёсывать файл на заголовки? Он может быть на много гигов, поэтому
file = io.open('file.txt'):read('*all') - не покатит.
Alexey
file:seek тоже не работает на много гигов
Snusmumriken
Saphire
Т.е. запрашивать файл по кускам, сканить, дальше идти.
Snusmumriken
Не идти дальше, а откатываться назад на длину заголовка и дальше идти, потому что мало ли, прям на разбивке буферов сидит заголовок распополамленный )))
Alexey
Хм, у меня работает.
Это платформо зависимо.
У меня file.write может писать файл лубого размера.
Но seek толко на 2 гига
Saphire
А, спасибо за такой случай
Alexey
Я пишу zip архивы ~3 гига
Snusmumriken
Ну ладно, ладно. Считаем что file:seek работает. Например, ограничение архива на два гига. Ничо страшного, для бОльших данных возьмём lua64.
Saphire
Тогда надо так - сохранить последние Н (где Н - самая большая длинна заголовка, и желательно заголовок корневого уровня сделать маленьким) байт блока, пойти к следующему, и через хитрую функцию поиска искать в этих двух кусках - маленьком и большом.
Snusmumriken
Saphire
Потом данные, потом копия заголовка.
Данные сами по себе могут иметь дальнейшую упаковку, или метаданные для извлечения настоящих данных, и т.д.
Snusmumriken
Две сигнатуры: начало и конец заголовка, каждый на три-пять символов, например.
Между ними - данные с разделителем, который тоже формализован.
Если нашли два начала заголовка подряд - считаем что второе истинное, мотаем до тех пор пока не наткнёмся на конец, считываем. Если и то и то верно но середина не парсится (неправильное количество разделителей, например) - значит это не заголовок.
Это я придумал ))
Saphire
Snusmumriken
Ну смотри. Второе начало заголовка - истинное, ибо первое - случайные данные. Шанс того что в файле сгенерируется структура "начало + три разделителя с данными + конец" - ниибацца мизерная.
Snusmumriken
Заголовок - сам себе сигнатура, полностью, панимаищь? )))
Saphire
* Инородные данные
* Сигнатура заголовка
- Разделитель
- Длинна (закодированная в плавающее число байт)
- Разделитель
- Чексумма длинны
- Разделитель
- Хеш всего сверху
* Наши данные (либо данные, упакованные во второй формат, с чексуммами и т.д., но это уже другое)
* Копия первого заголовка
Snusmumriken
Копия - уже избыточность.
И так заебись.
Saphire
Эм, а если у тебя имя файла - "cool thing [[[ awesome ||| thing ]]]!"?
fgntfg
Я тут подумал, а чего б данные не пихать до заголовка
Saphire
Snusmumriken
Неправильное количество данных в разделителе ))
А вот если вот такое:
"крутой файл [[[очень крутой файл|||5124|||deflate]]]" - то да, не покатит.
Найди человека который будет так называть файл )))
Snusmumriken
О, кстати.
Можно и это обойти.
Snusmumriken
В сигнатуре начала-конца заголовков присутствуют непечатаемые ascii-символы.
Saphire
Saphire
Заголовок неверен, а хвост реального не замечен.
Snusmumriken
Не распарсится.
Вместо "крутой" - должны быть цифры,
вместо "файл" - должно быть слово из набора.
fgntfg
рандомные данные [[[данные|||сигнатура|||длинна]]] рандомные данные
Snusmumriken
Конечно. Шанс найти неправильный заголовок - мизерен. Можно и проверки вставить, на всяк случ, чтобы уж точно ))
fgntfg
для большой рандомности можно пихать длину данных в хеш, по которому проверяется целосность данных. И считать хеш на лету, пока собираешь данные.
fgntfg
единственное что может пофачить - коллизии хешей
fgntfg
обычно указывают длину загаловка, а не ставят маркеры конца загаловка
Snusmumriken
Можно указывать длину, но тогда появляется лимит имени : )
А если я хочу имя на 100мб ))))
fgntfg
не появится, если указать длину имени
fgntfg
ну или хотябы порядок длины
fgntfg
типа 32 байта
Snusmumriken
Тогда уж ещё длину длины имени, чтобы в 32 байта влезло : )
fgntfg
ну если хочется борщить, то почему бы и нет.
fgntfg
и всё просолить хорошенечко
Snusmumriken
Я руководствовался комфортом.
Минимум отдельных процедур:
1. выдираем предполагаемые заголовки
2. сплитим то что получили на отдельные строки, не сплитится - или что-то неправильно - удаляем
3. парсим то что получилось в ООП-стайл.
Можно оптимальнее:
1. Выдираем заголовок и парсим его в ООП-стайл
2. Смещаемся на длину файла из заголовка
3. Ищем следующий заголовок
Так проще всего, на мой взгляд.
fgntfg
А можно еще и заголовки отдельно от данных хранить
Snusmumriken
Вот я думал на эту тему, но тогда не получится записывать в архив новые данные.
fgntfg
или даже хранить словарик с адресами начал ахивных данных
fgntfg
но всё это пустое
Snusmumriken
Можно-можно, но тогда сформировал архив - и всё тут, ничего не допишешь.
В моём варианте канают изменения файлов (ценой увеличения архива на их размер, избыточность но на крошечных файлах - канает, плюс типа история версий ))) и добавление новых.
fgntfg
у игры Смешбандикут были забавные приключение с умести игру на диск
fgntfg
почитай, там - космос
Snusmumriken
Хех, линк есть? : )
fgntfg
или видос на тытрубе глянь
Saphire
fgntfg
блин, я поищу
Saphire
Тогда твой формат. Ну, он много может отбросить файлов, если тебе попадется джекпот в виде тех возможных имён
Saphire
И вообще в топку имена в таком, на самом деле. Это должно быть уже в своих данных