Delphi: Определение типа файла по сигнатуре
Идея использования механизма разбора сигнатур возникла чуть более года назад при написании своего небольшого антивируса, входящего в состав SP-Монитора.
Если переименовать файл, сменив ему расширение, то иногда трудно определить, к какому типу данный файл относится. Рассмотренный ниже алгоритм позволит определять некоторые распространенные форматы файлов, а именно:
-
mp3 wav mid jpg gif mpg mpeg mov asf pdf class exe rar zip
Количество распознаваемых форматов Вы можете увеличить самостоятельно. Идея распознавания основана на том, что сигнатура заголовка файла определенного типа постоянна, и не меняется. Например, для exe-файлов первыми двумя байтами в файле являются "MZ", для zip-архивов "PK".
Проверка принадлежности файла к тому или иному формату состоит из двух этапов:


Остановимся на втором этапе.
Предварительно надо прочитать данные из файла в переменную MyBuf. О том, как правильно обращаться к файлам, как правильно читать из них отдельные байты без вызова исключительных ситуаций при совместном доступе к файлам будет рассказано в одной из следующих статей. А пока посмотрим на описание переменной MyBuf:
var MyByf: PСhar;
Для того, чтобы использовать оперативную память под нашу переменную, память надо зарезервировать:
// резервируем память для переменной работы с файлами GetMem(MyBuf, 10);
Вот текст функции:
// проверяем считанные байты.... function CheckSign: string; var res : boolean; res2 : string; begin res := true; res2 := 'unknown'; if (ord(MyBuf[0])=$ff) and (ord(MyBuf[1])=$fb) then begin res := false; res2 := 'mp3'; end; if res then if (ord(MyBuf[0])=$ff) and (ord(MyBuf[1])=$f3) then begin res := false; res2 := 'mp3'; end; if res then if (ord(MyBuf[0])=$52) and (ord(MyBuf[1])=$49) and (ord(MyBuf[2])=$46) and (ord(MyBuf[3])=$46) then begin res := false; res2 := 'wav mp3'; end; if res then if (ord(MyBuf[0])=$49) and (ord(MyBuf[1])=$44) and (ord(MyBuf[2])=$33) then begin res := false; res2 := 'mp3'; end; if res then if (ord(MyBuf[0])=$4d) and (ord(MyBuf[1])=$54) and (ord(MyBuf[2])=$68) and (ord(MyBuf[3])=$64) then begin res := false; res2 := 'mid'; end; if res then if (ord(MyBuf[0])=$ff) and (ord(MyBuf[1])=$d8) and (ord(MyBuf[2])=$ff) then begin res := false; res2 := 'jpg'; end; if res then if (ord(MyBuf[0])=$47) and (ord(MyBuf[1])=$49) and (ord(MyBuf[2])=$46) then begin res := false; res2 := 'gif'; end; if res then if (ord(MyBuf[0])=$00) and (ord(MyBuf[1])=$00) and (ord(MyBuf[2])=$01) then begin res := false; res2 := 'mpg mpeg'; end; if res then if (ord(MyBuf[4])=$6d) and (ord(MyBuf[5])=$6f) and (ord(MyBuf[6])=$6f) and (ord(MyBuf[7])=$76) then begin res := false; res2 := 'mov'; end; if res then if (ord(MyBuf[0])=$30) and (ord(MyBuf[1])=$26) and (ord(MyBuf[2])=$b2) then begin res := false; res2 := 'asf'; end; if res then if (ord(MyBuf[0])=$25) and (ord(MyBuf[1])=$50) and (ord(MyBuf[2])=$44) then begin res := false; res2 := 'pdf'; end; if res then if (ord(MyBuf[0])=$ca) and (ord(MyBuf[1])=$fe) and (ord(MyBuf[2])=$ba) and (ord(MyBuf[3])=$be) and (ord(MyBuf[4])=$00) then begin res := false; res2 := 'class'; end; if res then if (ord(MyBuf[0])=$4d) and (ord(MyBuf[1])=$5a) and (ord(MyBuf[2])=$90) and (ord(MyBuf[3])=$00) then begin res := false; res2 := 'exe'; end; if res then if (ord(MyBuf[0])=$52) and (ord(MyBuf[1])=$61) and (ord(MyBuf[2])=$71) and (ord(MyBuf[3])=$21) and (ord(MyBuf[4])=$1a) and (ord(MyBuf[5])=$07) then begin res := false; res2 := 'rar'; end; if res then if (ord(MyBuf[0])=$50) and (ord(MyBuf[1])=$4b) and (ord(MyBuf[2])=$03) and (ord(MyBuf[3])=$04) and (ord(MyBuf[4])=$1a) and (ord(MyBuf[5])=$07) then begin res := false; res2 := 'zip'; end; Result := res2; end;
По завершению программы не забываем очистить память от мусора. Т.к. мы сами выделили память для переменной MyBuf, то и нам эту память освобождать:
// Очищаем память FreeMem(MyBuf,10);
Функция написана. Она не идеальна, но поможет разобраться с разнотипными файлами.
Дополнительная информация на тему "работа с файлами":
Prolog — это язык логического программирования. Он является декларативным языком: вся стуктура программы представлена в виде правил и фактов. На нем можно строить экспертные системы, генерирующие ответы вида true (истина) или false (ложь). Пролог хорошо подходит для автоматического перебора вариантов решений с возвратами. Язык не требует написания большого объемного кода и позволяет получать отличные результаты.
Интересные материалы на сайте:
Для системных администраторов и любителей настраивать веб-сервера написана эта статья.
Небольшие рекомендации для системных администраторов, управляющих корпоративным почтовым сервером.
Анализ способов противодействия ненормативной лексике в онлайн-сервисах, таких как чаты, форумы, гостевые книги.
Для владельцев устаревшей морально и физически операционной системы Windows 98 посвящается статья о вреде использования этой операционной системы в локальной сети.