- PVSM.RU - https://www.pvsm.ru -
Привет!
Недавно задался вопросом а сколько байт необходимо для корректного определения mime типа файла. В первую очередь погуглив полученными ответами неудовлетворился и поэтому решил сам провести маленькое исследование на эту тему.

Для начало расскажу, что я нагуглил и почему мне это не понравилось:
Stack Overflow [1] дает 2 ссылки на википедию:
Теперь давайте перейдем собственно говоря к тому, что сделал я. Я написал очень маленькую программку, которая считывала все файлы из одной директории, копировала первые N байт в другую директорию, а затем по частичным копиям полученных файлов пыталась определить, а что это собственно говоря такое было. И так до тех пор, пока MIME-тип части файла не совпадет с MIME-типом оригинала. По результатам работы программа рапортовала, сколько байт понадобилось для определения того или иного типа. Вот ее код:
#include <stdio.h>
#include <stdlib.h>
#include <magic.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define TEST_DIR "test-dir/"
#define TMP_DIR "tmp-dir/"
magic_t cookie;
// Detects how many bytes required for correct MIME-type of this file
void detect_size(char *filename) {
int bytes = 1;
int infd, outfd;
char strin[100], strout[100], type[100];
char buf[4096];
strcpy(strin, TEST_DIR);
strcat(strin, filename);
strcpy(strout, TMP_DIR);
strcat(strout, filename);
while(1) {
// Make a copy of given file
infd = open(strin, O_RDONLY);
outfd = open(strout, O_RDWR | O_CREAT, 00666);
read(infd, &buf, bytes);
write(outfd, &buf, bytes);
lseek(infd, 0, SEEK_SET);
lseek(outfd, 0, SEEK_SET);
// Detect mime types of old and new
const char *mime_type = magic_descriptor(cookie, infd);
strcpy(type, mime_type);
mime_type = magic_descriptor(cookie, outfd);
// Check if mime type detected correctly
if (strcmp(mime_type, type) == 0) {
printf("%s detected correctly in %d bytesn", type, bytes);
unlink(strout);
return;
}
unlink(strout);
bytes++;
}
}
int main() {
DIR *dirfd = opendir(TEST_DIR);
struct dirent entry, *result = NULL;
cookie = magic_open(MAGIC_MIME_TYPE | MAGIC_ERROR);
magic_load(cookie, NULL);
while(1) {
readdir_r(dirfd, &entry, &result);
if (result == NULL)
break; // No more entries in this directory
if (!strcmp(entry.d_name, ".") || !strcmp(entry.d_name, ".."))
continue; // Ignore "." and ".."
detect_size(entry.d_name);
}
magic_close(cookie);
closedir(dirfd);
exit(EXIT_SUCCESS);
}
Потом накидав кучку разных файлов в папку test-dir я начал экспериментировать. Конечно то, что я сделал ни как не тянет на полномасштабное и серьезное исследование, но некоторые результаты все таки интересны. Приведи их краткую сводку:
application/x-sharedlib detected correctly in 18 bytes
application/msword detected correctly in 1793 bytes
image/gif detected correctly in 4 bytes
application/zip detected correctly in 4 bytes
application/x-dosexec detected correctly in 2 bytes
application/vnd.oasis.opendocument.presentation detected correctly in 85 bytes
text/html detected correctly in 14 bytes
image/jpeg detected correctly in 2 bytes
application/x-executable detected correctly in 18 bytes
text/x-makefile detected correctly in 1594 bytes
application/x-executable detected correctly in 18 bytes
application/x-gzip detected correctly in 2 bytes
audio/mpeg detected correctly in 2291 bytes
text/x-c detected correctly in 27 bytes
audio/x-flac detected correctly in 4 bytes
application/pdf detected correctly in 5 bytes
Отмечу некоторые вещи, которые мне показались интересными:
Ну это пожалуй все, что я хотел рассказать в этот раз, не люблю много писать. Надеюсь, что это статья окажется кому-нибудь интересной.
Спасибо за внимание.
Автор: yulyugin
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/39000
Ссылки в тексте:
[1] Stack Overflow: http://stackoverflow.com/questions/8673407/how-many-bytes-are-required-for-accurate-mime-type-detection
[2] File Signature: http://en.wikipedia.org/wiki/File_signature
[3] List of signatures: http://en.wikipedia.org/wiki/List_of_file_signatures
[4] File Signatures: http://filesignatures.net/index.php?page=all
[5] Источник: http://habrahabr.ru/post/186828/
Нажмите здесь для печати.