Оценка изменения в бинарном файле

Доброго времени суток.
Недавно в универе предложили задачу для получения досрочного получения зачета.
Звучит она так.
Создание компонента на c++ и winapi32, который отслеживает изменение в наборе бинарных файлов, и оповещает в каком именно. Можно без детализации.
Сам вопрос у меня такой, как лучше это сделать, при этом не делая код слишком громоздким.
И если есть какие то примеры, то скинуть для просмотра.
Заранее спасибо.

Проверять дату последнего изменения и сравнивать ее с датой из базы данных
Если произошло изменение, даты буду различаться
Записываем новую дату и оповещаем в файл лога об изменении
Если подождете могу дать реализацию на Bourne again she'll, надо?

Отслеживать дату — слишком слабо. Можно внести изменения в файл не изменяя дат. Можно изменить дату без изменения содержимого файла. Я бы использовал хэш-функцию в добавление к длине файла. Посмотри статью по ссылке и далее по ссылкам. В Википедии есть исходники для некоторых хэш-функций.

Можно использовать MD5 из WinAPI: пример из MSDN.

Для ускорения процесса я бы сначала проверял длину файла. Если она совпадает, тогда вычисление хэша и его проверка.

Алгоритм, описанный мною, требует меньшее кол-во действий(а следовательно и более легок для восприятия) и, скорее всего, будет работать быстрее. Есть такая концепция, называется KISS, почитайте, очень полезно. Если вы сомневаетесь в приведенных мною аргументах, я могу предоставить вам пример из жизни(моей и, наверное,вашей),когда программа, действующая по приведенному мною алгоритму применялась(и применяется) очень часто по сравнению с другими аналогами.

Есть такая концепция, называется KISS, почитайте, очень полезно.

Обязательно почитаю.

Всё следует упрощать до тех пор, пока это возможно, но не более того.
Альберт Эйнштейн

GreenHope, вы внимательно читали мой пост? Первые три предложения? Мне кажется, что приведенных мною аргументов достаточно, что бы не упрощать «более того».

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

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

Может вы меня не совсем правильно поняли. Под датой я понимаю строку в формате Час/Минута/Секунда/День/Месяц/Год(можно в другом порядке), причем файл, редактируемый последним, будет иметь другую дату редактирования, более позднюю, в любом случаем(если на редактирование файла уходит меньше секунды, можно будет добавить поле милесекунд). Средство stat bash позволяет делать это быстро(если использовать так-же построчный анализ вывода данной команды). Зачем изобретать заного велосипед? Я уверен, что DOS консоль имеет схожие инструменты анализа даты последнего изменения. Т.е. можно написать скрипт на Perl(который доступпен и там и там), а реализацию проверки дат можно сделать отдельно. Тогда программу можно будет легко перенести на другие ОС, в которых доступен интерпритатор Perl и средства командно строки.

Спасибо всем за ответы.
Мне тоже ближе оцена через хеш сумму, но как пример сделаю наверно оба варианта, хуже не будет.
Где можно подробнее почитать, желательно с разбором вариантов, насчет оценки через хеш сумму. Думаю уже есть реализация данного компонента, интересно было бы глянуть. Сам сяду вплотную на выходных за эту задачу

Или я где-то не фтыкаю, или сейчас стало модно читать через строчку ((

Задание:

Создание компонента на c++ и winapi32, который отслеживает изменение в наборе бинарных файлов, и оповещает в каком именно. Можно без детализации.

Какой, нах, bash, PowerShell и Perl в придачу?? c++ и winapi32!

Может вы меня не совсем правильно поняли. Под датой я понимаю строку в формате

GreenHope, я-то вас отлично понял, а вот вы меня даже со второго раза не поняли. Еще раз повторю:

Отслеживать дату — слишком слабо. Можно внести изменения в файл не изменяя дат. Можно изменить дату без изменения содержимого файла.

castly, в моём более раннем ответе на ваш вопрос я дал две ссылки, и selevit в своем посте одну.

Еще меня в задании несколько смущает слово «компонент». Компонент чего? Или для чего? Почему не «программа» или «приложение»? Термин «компонент» используется в контексте программирования под .NET, тогда причем здесь winapi32?


Кстати, интересный момент, на который обратил внимание selevit: "компонент ... отслеживает изменение в наборе бинарных файлов". Т.е. можно понимать так, что запущенная программа (хм... компонент) поднимает тревогу каждый раз, как только был изменен один из контролируемых файлов. Это можно сделать либо как подсказал selevit (посчитав .NET частью winapi32), либо, используя FindFirstChangeNotification, отслеживать изменение каталога и при изменении проверять файлы, либо тупо в цикле проверять наличие/длину/дату всех файлов из набора и при несоответствии проверять по хэш-сумме, либо перехватывать функции WinAPI, ответственные за модификацию файла (но это гемор и вообще неспортивное поведение).

Еще, кстати, в задании сказано о «наборе файлов». А вот о том, что они собраны в одном каталоге — нет. Так что «возможны варианты».

По ходу проще зачет вместе с группой получать...

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

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

Почти все популярные ОС имеют встроенные механизмы для асинхронной работы с ФС. Их и нужно использовать для таких задач.

А ни кто и не говорил, что будет все быстро и просто. Поэтому, как я уже писал, проверку изменения файлов лучше делать от простого к сложному: сначала длину, потом дату, а уже в конце проверка хэш-суммы. Но это не интересно. Как делать — понятно.

Непонятно — как сделать отслеживание в реальном времени. Т.е. фиксировать попытку изменения файла.

Почти все популярные ОС имеют встроенные механизмы для асинхронной работы с ФС. Их и нужно использовать для таких задач.

Это был намек на что-то? Что можно использовать под Виндой для отслеживания попыток изменения файлов, расположенных произвольно?

Как вы сами сказали: «можно изменить файл, не изменяя дату.»
Да, и файл можно изменить, не изменяя размер.

Кажется товарищ селвит говорит а жарнулируемости ФС?

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

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

Как вы сами сказали: «можно изменить файл, не изменяя дату.»
Да, и файл можно изменить, не изменяя размер.

Все правильно. Поэтому проверки от простых к сложным. Если файл не прошел проверку на размер или дату — значит он точно изменен. В данном случае, простые проверки не дают 100%-ой гарантии. Хэш, при правильном использовании, такую гарантию дает, но метод затратный.

Это был намек на что-то? Что можно использовать под Виндой для отслеживания попыток изменения файлов, расположенных произвольно?

Никаких намеков, я вроде-бы предельно конкретно выражаюсь. Можно повесить асинхронный обработчик на изменение любого файла, а неотслеживаемые пути фильтровать уже в этом этом обработчике. Вот пример обработчика на изменение, создание и удаление файлов.
https://msdn.microsoft.com/ru-ru/library/system.io.filesystemwatcher(v=vs.90).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-4

А вообще, нужно более внимательно поштрудить документацию MSDN и, уверен, что найдется способ повесить обработчики изменений на конкретные файлы, либо один обработчик на множество файлов.

В Linux есть механизм select, через который решаются подобные задачи.

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

На самом деле, нет. Один и тот же хеш может быть одинаковым для разных файлов. Но современные алгоритмы хеширования, например SHA-256, минимизируют риск коллизий.

Спасибо за ссылки, разобрался и даже написал.
Такой вопрос, как можно определить откуда изменили файл? Или что?
Вирус, к примеру. Или какой юзер это сделал?
Или ткните носом где об этом можно почитать?

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

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

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.