Riconoscimento del MIME Type attraverso il Magic number

MarcoGrazia

Utente Attivo
15 Dic 2009
813
18
18
59
Udine
www.stilisticamente.com
Ciao, quella che presento qui è una semplice routine in grado di lggere il Magic number di un file e quindi stabilirne il tipo MIME.
Chiaramente non è risolutiva ne vuole esserlo, ma l'ho testata con alcuni dei file che gestisce e mi pare ben funzionante.
In pratica la utilizzo per il controllo remoto dell'invio di alcuni tipi di file attraverso la LAN che gestisco.
La routine la metto qui ed è abbastanza autoesplicativa, almeno spero.
PHP:
function minimime($fname) {
    $fh = fopen($fname, 'rb');    //    Legge il file passato alla funzione come binario
   
    //    Se il file handle non è false, continua nella lettura.
    if ($fh) {
        $bytes6 = fread($fh, 6);    //    legge 6 caratteri
        fseek($fh, 0);    //    torna a puntare il primo carattere del file ( il carattere 0 )
        $bytes8 = fread($fh, 8);    //    legge 8 caratteri per usi futuri.
        fclose($fh);     //    Chiude il file in lettura.
       
        //    Se sono stati letti dei byte prosegue, se no esce a false.
        if ($bytes6 === false) return false;
        //    IMG
        if (substr($bytes6, 0, 3) == "\xff\xd8\xff") return 'image/jpeg';            //    Immagini JPG
        if (substr($bytes6, 0, 2) == "\x42\x4D") return 'image/x-windows-bmp';        //    Immagini BMP
        if ($bytes6    == "\x89PNG\x0d\x0a" || $bytes6    == "\x89\x50\x4E\x47\x0D\x0A") return 'image/png';        //    Immagini PNG
        if ($bytes6    == "\x47\x49\x46\x38\x37\x61" || $bytes6 == "\x47\x49\x46\x38\x39\x61") return 'image/gif';        //    Immagini GIF di ogni tipo previsto
        if ($bytes6    == "GIF87a" || $bytes6 == "GIF89a") return 'image/gif';        //    Stessa cosa di cui sopra, ma utilizzando i caratteri esadecimali.
        if (substr($bytes6, 0, 4) == "\x49\x49\x2A\x00" || substr($bytes6, 0, 4) =="\x4D\x4D\x00\x2A") return 'image/tiff';        //    Immagini TIFF ( generalmente per i FAX )
        //    PDF
        if ($bytes6 == "%PDF" || substr($bytes6, 0, 4) == "\x25\x50\x44\x46") return 'application/pdf';        //    PDF
        //    ZIP, RAR file or 7z
        if (substr($bytes6, 0, 2) == "PK" || substr($bytes6, 0, 2) == "\x50\x4B") return 'application/zip';        //    ZIP File
        if ($bytes6 == "\x52\x61\x72\x21\x1A\x07") return 'application/x-rar-compressed';                        //    RAR File
        if ($bytes6 == "\x75\x73\x74\x61\x72") return 'application/x-tar';                                        //    Archivi TAR
        if (substr($bytes6, 0, 2) == "7z" || $bytes6 == "\x37\x7A\xBC\xAF\x27\x1C") return 'application/x-7z-compressed';        //    7Z file
        //    ELSE
        return 'application/octet-stream';    //    Generic file    Generico se non è tra questi.
    }
    return false;  //  Esce in errore
}    //    minimime()
L'embrione l'ho trovato su un sito cercando un metodo semplice per gestire il mime type di un file caricato, ma poi l'ho ampliata e modificata al meglio che potevo, è abbastanza veloce.
Il funzionamento è semplice: passato il nome di un file, che si deve trovare nel percorso del file system dove gira l'applicazione, questo viene aperto in lettura di tipo binario.
Se non ci sono errori di sorta continua con la lettura dei primi 6 caratteri del file, apltrimenti esce con un false.
C'è anche una variabile che legge i primi 8 caratteri del file, ma per ora non è usata, quindi chiude il file, e prosegue con l'interpretazione dei caratteri letti.
Il magic number, dovrebbe essere interpretato proprio nei primi 6 caratteri di ogni file, ma è una pia illusione, in realtà può essere anche utilizzato nei primi due caratteri come nei file ZIP, che riportano solo PK, le iniziale del loro inventore: Phill Katz.
Comunque interpretato il file, viene ritornato il suo mime type e quindi la routine esce.

Qui sotto si vede un suo semplice utilizzo, chiamandola con un file in lettura, ho pure passato un mio vecchio CUD :D e l'ha letto perfettamente interpretandolo come PDF.
PHP:
echo minimime('CUD_01856613_2014_0.pdf') . '<br>';       //    Torna application/pdf
echo minimime('administrator.png') . '<br>';            //    Torna image/png
echo minimime('AtomSetup.exe') . '<br>';                //    Torna un application/octet-stream dato che il file exe non è contemplato.
echo minimime('error-404.jpg') . '<br>';                //    Torna image/jpeg
La routine non verifica DLL e file EXE perché non mi serve farlo, però posso solo aggiungere al riguardo che nel caso voleste ampliarla in tal senso, dovrete verificare il tipo di sistema operativo in uso, perché nel tempo i modelli sono cambiati e bisogna verificare se si tratta di DOS executable, DOS stub, Windows in modalità Portable Executable, ELF, insomma un casino :D

Per chi si vuole divertire a modificarla e ad ampliarla qui un piccolo elenco di magic number: https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files
E qui un elenco di mime type: https://www.sitepoint.com/mime-types-complete-list/
 
Discussioni simili
Autore Titolo Forum Risposte Data
M [PHP] Problemi con il riconoscimento login. PHP 21
A [PHP] Riconoscimento Utente Loggato PHP 7
W Riconoscimento pc nella rete intranet PHP 14
A riconoscimento sito da parte di google WordPress 6
V Mancato riconoscimento HD esterno USB Hardware 0
I login due volte per il riconoscimento PHP 12
asevenx problema riconoscimento ip tra form e database diversi PHP 1
helpdesk riconoscimento acquisto PHP 15
S Riconoscimento Browser Javascript 1
I Apertura e scrittura iframe, il riconoscimento delle porzioni! Link cambio stile. Javascript 0
Sergio Unia Problema con gli eventi del mouse su una data table: Javascript 2
D Visualizzazione pagina basata sul valore di un campo del database PHP 2
Barierta Testo a comparsa con passaggio del mouse Javascript 17
W Elenco dei link del file presenti in una cartella PHP 2
C Dopo chiusura del tag php la stringa html va a capo PHP 1
R Trovare la Tabella del pagamento su WooCommerce WordPress 0
R Barra del menù principale decentrata Joomla 4
L titolo del sito nella pagina di ricerca di google SEO e Posizionamento 2
A Copertura: indicizzata, non inviata nella mappa del sito XML 1
felino Stampante Epson XP-322: nessuna traccia del colore nero! Hardware 6
M Controllo del codice fiscale/partita iva PHP 11
felino [JQuery] Append dopo ultimo ul li del primo livello jQuery 2
A fread non legge il contenuto del file PHP 4
F Aggiungere automaticamente sito a home del telefono HTML e CSS 2
C Saluti a tutti gli utenti del Forum Presentati al Forum 0
S Trasferire dati sulle pagine del sito PHP 7
V [Buoni amazon]+[Itunes] legali e scontati del 25% Altri Annunci 0
Mastiff_84 Saluto a tutti i membri del forum Presentati al Forum 1
D Aumentare i sublevel del menù del theme Webdesign e Grafica 1
A Ciao popolo del forum Presentati al Forum 0
T Dubbio su costante ROOT, che rappresenti la base directory del sito PHP 4
T Campi static del Controller generico si azzerano ad ogni richiesta PHP 3
F Creare un set di date a seconda del frazionamento scelto da inserire in MySQL PHP 6
felino [Wordpress] Modifica main color del template WordPress 8
D Logout che rientra col tasto indietro del browser PHP 5
felino Bug estetici del nuovo layout Supporto Mr.Webmaster 1
marino51 Restyling del forum 12/2019 - Critiche, segnalazioni e opinioni Discussioni Varie 7
F Opzione cambia aspetto del sito PHP 1
camilia Come posso dividere le grandi dimensioni del file PST? Windows e Software 2
Gabriele15497514 php testo errato durante la lettura del file txt quando lo script viene eseguito contemporaneamente PHP 3
M [PHP] elencare e conteggiare dati di una colonna del db PHP 13
P Nuovo del forum Presentati al Forum 0
K [ASP] Visualizzare nome del file selezionato Classic ASP 3
gandalf1959 Estrazione e visualizzazione del simbolo dell'euro php/mysqli PHP 0
maxnegri Eliminare url index.php con variabili e reindirizzare alla home del sito PHP 7
D [ASP] Autocomplete cerca su 2 campi del db Classic ASP 1
G gioco del tris con i vettori c++ C/C++ 1
F [PHP] modifica del body email con checked PHP 8
U Progettazione del mio Centro Stella Reti LAN e Wireless 0
elpirata [MYSQL] Schedulare evento per update del campo data su tabella MySQL 0

Discussioni simili