www.gcmsite.ru

Новости Программы PHP-скрипты Статьи Числа
Услуги Резюме Игры Автомобили Поиск

СИСТЕМНОЕ И ВЕБ-ПРОГРАММИРОВАНИЕ
компьютерная техника, игры

Delphi: Определение типа файла по сигнатуре

Идея использования механизма разбора сигнатур возникла чуть более года назад при написании своего небольшого антивируса, входящего в состав SP-Монитора.

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

    mp3 wav mid jpg gif mpg mpeg mov asf pdf class exe rar zip

Количество распознаваемых форматов Вы можете увеличить самостоятельно. Идея распознавания основана на том, что сигнатура заголовка файла определенного типа постоянна, и не меняется. Например, для exe-файлов первыми двумя байтами в файле являются "MZ", для zip-архивов "PK".

Проверка принадлежности файла к тому или иному формату состоит из двух этапов:

    чтение 7 первых байт исследуемого файла
    проверка некоторых байт, детектирование

Остановимся на втором этапе.

Предварительно надо прочитать данные из файла в переменную 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);

Функция написана. Она не идеальна, но поможет разобраться с разнотипными файлами.

Дополнительная информация на тему "работа с файлами":


Apache — это кросплатформаенное программное обеспечение, относящееся к классу http-серверов. Поддерживается множеством операционных систем: Windows, Linux, MacOS и т.д. Одним из ключевых факторов в вопросе использования данного web-сервера является гибкость настройки и надежность выполнения операций. Apache включает в себя множество дополнительных модулей, позволяющих работать с различными базами данных, контролировать аутентификацию пользователей и т.д.

Интересные материалы на сайте:

Автор, разработчик: Шаров Евгений   (gcmsite@yandex.ru)
(c) 2000-2020 GCM-Site - системное и веб-программирование
Цитирование материалов сайта возможно только при наличии гиперссылки