LINUX.ORG.RU

Проверка целостности файла

 , , , ,


0

2

Есть игра для Android, которая разделена на две части - apk (сама игра) и obb (ресурсы, которые лежат на сервере гугеля).

Игра при старте должна проверить наличие и целостность obb (в моем случае это обычный zip). Если файла нет или он поврежден, то игра должна его скачать с сервера заново.

Вопрос, как проверить целостность архива? Проверять crc каждого файла в архиве - пользователь скажет «вот говно», и удалит игру. И будет совершенно прав.

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

Была идея дописывать размер файла в конец архива, а при старте игры сверять текущий размер с размером, приписанным в конце.
Но как на это посмотрит zlib? Правильное ли это решение?

Буду рад любой идее или совету.

★★★★★

но задолбало каждый раз хардкодить размер файла при обновлении ресурсов игры.

Ну так не хардкодь - в первый раз игра качает файл? Сохраняй в настройках приложения.

ziemin ★★ ()
Ответ на: комментарий от ziemin

Ну так не хардкодь - в первый раз игра качает файл? Сохраняй в настройках приложения.

1. Соединение может разорваться до того, как будет скачан файл.
2. Умный пользователь может решить освободить место на флешке.
3. ФС может глюкануть.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

1. Соединение может разорваться до того, как будет скачан файл.

Ну так и размер будет отличаться, если его узнать перед скачиванием, а не самому считать байты (или как ты там делаешь)

2. Умный пользователь может решить освободить место на флешке.

Ну ту же сам писал:

Если файла нет или он поврежден, то игра должна его скачать с сервера заново.

3. ФС может глюкануть.

Может запихнуть между файлами ресурсов 1К файлики с известным содержимым - распаковать сотню файлов для проверки быстрее, чем весь архив тестить.

ziemin ★★ ()
Ответ на: комментарий от ziemin

Кстати погуглил бы - навернаяка zip содержит свой размер.

ziemin ★★ ()

Проверять crc каждого файла в архиве

А зачем каждого файла? Почему бы в apk не положить хэш архива, а после скачивания/когда-там надо не посчитать его заново и сравнить ?

roy ★★★★★ ()

хм... положи рядом с архивом файл с кодами верификации. Хоть размер там храни, хоть мд5.

Вот есть к примеру файл game.obb, положи рядом game.verify, в нем просто строкой md5 содержимого game.obb. Тащишь game.verify, получаешь содержимое, сверяешь md5 с имеющимся файлом: не свопадает - перекачиваем.

bvn13 ★★★★★ ()
Ответ на: комментарий от roy

А зачем каждого файла? Почему бы в apk не положить хэш архива, а после скачивания/когда-там надо не посчитать его заново и сравнить ?

Считать хеш придется КАЖДЫЙ раз после обновления ресурсов. Посчитать хеш далеко не маленького бинаря на мобильнике - еще та «прелесть».

И как вы себе представляте «положить внутрь архива хеш», который еще не посчитан?

andreyu ★★★★★ ()
Ответ на: комментарий от bvn13

хм... положи рядом с архивом файл с кодами верификации. Хоть размер там храни, хоть мд5.

Там, где хранится obb, я не имею права хранить иные файлы.

Вот есть к примеру файл game.obb, положи рядом game.verify, в нем просто строкой md5 содержимого game.obb.

Сколько по времени займет расчет md5 на мобильнике файла размером хотя бы мег 10?

Тащишь game.verify, получаешь содержимое, сверяешь md5 с имеющимся файлом: не свопадает - перекачиваем.

Меня устроит и размер файла, но я не хочу его хардкодить в игру каждый раз, когда меняются ресурсы.

andreyu ★★★★★ ()
Ответ на: комментарий от ziemin

Ну так и размер будет отличаться, если его узнать перед скачиванием, а не самому считать байты (или как ты там делаешь)

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

andreyu ★★★★★ ()
Ответ на: комментарий от ArturK

В первый раз проверить по md5, а в следующие разы запускать без проверки.

Один раз?

2. Умный пользователь может решить освободить место на флешке.
3. ФС может глюкануть.
andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Но ведь это не очень частое явление, а так сказать форс мажор.

Умный пользователь может решить освободить

он ссзб

ArturK ()
Ответ на: комментарий от andreyu

Смотря как ты его качаешь. По первой же ссылке в гугле

URL url = new URL(sUrl[0]);
URLConnection connection = url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();

ziemin ★★ ()

1. Самому сделать md5 хеш и положить в файл, который качается.

2. После скачки ресурсов при первом старте проверять хеш, дабы убедиться в целостности скачки

3. Потом использовать проверку размера. А размер можно опять же ложить в файлик рядом.

В чем проблема то?

pztrn ★★★★ ()
Ответ на: комментарий от ArturK

Умный пользователь может решить освободить

он ссзб

Безусловно, виноват он. Но что он сделает, если игра крешнется? Плюс в статистику анинстолов :)

andreyu ★★★★★ ()
Ответ на: комментарий от ziemin

Смотря как ты его качаешь. По первой же ссылке в гугле

С сервера гугеля. Используется для этого apx. Для скачивания будет предоставлено то, что привязано к последнему добавленному apk. Просто так попросить гугелль отдать нужный мне файл я не могу. Неподписанному приложению, или приложению с другой подписью файл гугель не отдаст.

andreyu ★★★★★ ()
Ответ на: комментарий от pztrn

1. Самому сделать md5 хеш и положить в файл, который качается.
2. После скачки ресурсов при первом старте проверять хеш, дабы убедиться в целостности скачки

Можно алгоритм этих пунктов?

1. Создаю файл с ресурсами.
2. Считаю его md5.
3. Добваляю в файл с ресурсами md5.
4. Теперь у меня файл с ресурсами и md5, который уже невалиден.

Я правильно понял вас?

3. Потом использовать проверку размера. А размер можно опять же ложить в файлик рядом.
В чем проблема то?

Я по настоянию гугеля не имею права класть что-либо рядом с этим файлом. Можно забить на эту просьбу и положить файл рядом, а потом наткнуться на грабли.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Сколько по времени займет расчет md5 на мобильнике файла размером хотя бы мег 10?

пару секунд максимум на современной мобиле.

true_admin ★★★★★ ()

Ну а так посмотри что умеет твоя либа. В zip, вроде, crc файлов есть, так что теоретически проверить не проблема. Накрайняк unzip -t <имя файла>

true_admin ★★★★★ ()

Как вариант, можно пробежаться по файлу и проверить его структуру (прочитав заголовки файлов), с большой долей вероятности архив будет цел, если цела и его структура.

qbe ()
Ответ на: комментарий от true_admin

пару секунд максимум на современной мобиле.

Вы это проверяли, или просто ваше предположение? Файл придется читать с флешки (а они далеко не во всех мобилах шустрые) - тут уже в пару секунд никак не уложиться.

В любом случае, вопрос о том, где хранить эталонную md5 остается открытым.

andreyu ★★★★★ ()
Ответ на: комментарий от true_admin

Ну а так посмотри что умеет твоя либа. В zip, вроде, crc файлов есть, так что теоретически проверить не проблема. Накрайняк unzip -t <имя файла>

В теории да, не проблема. Но эта теория далека от практики.

andreyu ★★★★★ ()
Ответ на: комментарий от qbe

Как вариант, можно пробежаться по файлу и проверить его структуру (прочитав заголовки файлов), с большой долей вероятности архив будет цел, если цела и его структура.

Да, о таком варианте я писал в самом начале, но это далеко не шустрая процедура.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Вы это проверяли

угу, гуглил бенчмарки md5

Файл придется читать с флешки (а они далеко не во всех мобилах шустрые) - тут уже в пару секунд никак не уложиться.

Это не проблемы md5. Ты сначала определись какого уровня проверка тебе нужна. Если читать файл целиком не вариант то забудь о полной контрольной сумме и не спрашивай «где мне хранить md5».

где хранить эталонную md5 остается открытым.

Припиши в конец файла. Потом я же писал что у самого zip есть и свои контрольные суммы.

true_admin ★★★★★ ()
Ответ на: комментарий от andreyu

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

anonymous ()

Размер + checksum n байтов равномерно распределенных по архиву, где n это устраивающая тебя производительность.

Legioner ★★★★★ ()
Ответ на: комментарий от andreyu

Да, о таком варианте я писал в самом начале, но это далеко не шустрая процедура.

Ну если читать ТОЛЬКО заголовки, то шустрая (если только число файлов не тысячи ;)

Кстати, насчёт размера файла - в конце файла записана структура End of central dir record, в которой присутствует поле zipfile comment. В него можно занести ожидаемый размер файла, контрольную сумму или что-нибудь ещё.

А если прочитать файл с конца, и проверить валидность записи End of central dir record, (хотя бы по сигнатуре 0x06054b50), можно уже удостовериться, что архив сохранил свой размер.

qbe ()
Ответ на: комментарий от true_admin

у самого zip есть и свои контрольные суммы.

Емнип, эти контрольные суммы относятся к несжатым данным, так что менее затратно будет весь архив обсчитать. Но да, метод самый простой, без костылей.

qbe ()
Ответ на: комментарий от andreyu

Нет, на ББ считай. А сумму ложи в файл рядом. А как положишь в файл - на сервер гугеля, или же качать этот файл с хешсуммой - уже тебе решать.

pztrn ★★★★ ()
Ответ на: комментарий от qbe

Емнип, эти контрольные суммы относятся к несжатым данным

дык это же то что нужно. Осталось только проверить не делает ли проверок сама либа (zlib?) при распаковки. Мне в сырцы лазить лень, в гугл тоже :)

true_admin ★★★★★ ()
Ответ на: комментарий от tailgunner

Добавь CRC32 (или MD5) после конца файла.

Тоже думал об этом и в топике спросил, правильно ли так делать?
Проверить, пережует ли это zlib можно, но не огребу ли я грабли в дальнейшем?

andreyu ★★★★★ ()
Ответ на: комментарий от true_admin

Это не проблемы md5.

Да, это моя проблема и девайса, на котором будет проводится расчет.

Ты сначала определись какого уровня проверка тебе нужна.

Как я написал в самом начале, меня устроит проверка размера файла.

Если читать файл целиком не вариант

Зачем для этого читать целиком весь файл? Блоками нельзя?

то забудь о полной контрольной сумме и не спрашивай «где мне хранить md5».

Я не спрашивал, где мне хранить md5. Я пытался понять, как pztrn умудрился добавить в архив файл с md5, не испортив md5 полученного архива.

Припиши в конец файла.

Похоже, что топик вы вообще не читали :)

Потом я же писал что у самого zip есть и свои контрольные суммы.

А я писал, что это дорогая по времени операция.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Не знаю про zlib, но unzip это перенес. Другое дело, что, если ты упираешься в скорость чтения из ФС, сама идея вычисления контрольной суммы (любой) провальная.

tailgunner ★★★★★ ()
Ответ на: комментарий от anonymous

пару секунд в худшем случае

Пара секунд - это «давай досвидания, тормозная игра».

и что слюной брызгать, поставь калькулятор хэша под андроид, да и увидишь сам

Отойдите от окна, если на вас попадают брызги - на улице дождь.

andreyu ★★★★★ ()
Ответ на: комментарий от Legioner

Размер + checksum n байтов равномерно распределенных по архиву, где n это устраивающая тебя производительность.

Мля, где мне хранить этот размер? Где мне хранить контрольную сумму? Я же написал, надоело хардкодить размер файла в игре. Это жудко неудобно и лишняя история коммитов в репозитории.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

как pztrn умудрился добавить в архив файл с md5, не испортив md5 полученного архива.

никак, надо отрезать перед расчитыванием

это дорогая по времени операция.

Я надо ли её вообще делать? Если архив битый то при распаковке оно само выкинет эксепшн рано или поздно (наверно, это надо проверить).

true_admin ★★★★★ ()
Ответ на: комментарий от qbe

А если прочитать файл с конца, и проверить валидность записи End of central dir record, (хотя бы по сигнатуре 0x06054b50), можно уже удостовериться, что архив сохранил свой размер.

О, отличная идея, спасибо.

andreyu ★★★★★ ()
Ответ на: комментарий от pztrn

Нет, на ББ считай.

На чем, простите?

А сумму ложи в файл рядом. А как положишь в файл - на сервер гугеля, или же качать этот файл с хешсуммой - уже тебе решать.

Я не могу положить на сервер гугеля произвольное кол-во файлов. Я могу положить туда obb и patch.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Зачем для этого читать целиком весь файл? Блоками нельзя?

Поблочно? Можно.

топик вы вообще не читали :)

Читал, но я не понимаю чем не устраивают предложенные варианты. В частности отказаться от предварительной проверкии вообще и ловить exception-ы при распаковке.

true_admin ★★★★★ ()
Ответ на: комментарий от tailgunner

Не знаю про zlib, но unzip это перенес.

Просто дописать в конец файла пару байт можно без проблем? Если так, то это подходящее решение.

Другое дело, что, если ты упираешься в скорость чтения из ФС, сама идея вычисления контрольной суммы (любой) провальная.

Да, чтение с флешки на многих файлах далеко не шустрое. Но хранение размера файла, как приписка нескольких байт меня устроит.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Нет, на ББ считай.

На чем, простите?

Бодрая Белка, вестимо По-моему нетбукоюзеры так стационарный компьютер называют. Типа «Большой Брат»

ArturK ()

я не знаю как в андроиде, но обычно харкорится публичный ключ, а приватным ключом ты подписываешь второй файл. Тогда программа может проверять твою ЭЦП, причём ты можешь менять второй файл, без замены самой программы. man gpg короче.

drBatty ★★ ()
Ответ на: комментарий от bvn13

хм... положи рядом с архивом файл с кодами верификации. Хоть размер там храни, хоть мд5.

умный пользователь может подложить файл в 0 байт и md5 к нему ☺

drBatty ★★ ()
Ответ на: комментарий от true_admin

никак, надо отрезать перед расчитыванием

Я понял, что он не дописал raw-data в конец файла, а добавил файл с md5 внутри внутрь архива.

Я надо ли её вообще делать?

Сейчас не делаю.

Если архив битый то при распаковке оно само выкинет эксепшн рано или поздно (наверно, это надо проверить).

И что делать? «Дорогой пользователь, ресурсы оказались битые, нужно скачать их сначала. Все, что было нажито непосильным трудом мы постараемся сохранить, но гарантии не даем» :)

andreyu ★★★★★ ()
Ответ на: комментарий от ArturK

По-моему нетбукоюзеры так стационарный компьютер называют. Типа «Большой Брат»

Ну посчитаю я контрольную сумму на ББ. Как это мне поможет не считать контрольную сумму на мобильном девайсе?

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Сколько по времени займет расчет md5 на мобильнике файла размером хотя бы мег 10?

его надо делать только после посл. скачивания файла. Потом достаточно временного штампа.

drBatty ★★ ()
Ответ на: комментарий от drBatty

а там у вас разве нет TIMESTAMP посл. модификации?

А его наличие поможет как то решить проблему озвученную в этом топике?

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Дорогой пользователь, ресурсы оказались битые, нужно скачать их сначала

Да, отличный вариант.

true_admin ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.