Riconoscimento del MIME Type attraverso il Magic number

Discussione in 'Snippet PHP' iniziata da MarcoGrazia, 8 Giugno 2018.

Tag (etichette):
  1. MarcoGrazia

    MarcoGrazia Utente Attivo

    Registrato:
    15 Dicembre 2009
    Messaggi:
    661
    Mi Piace Ricevuti:
    7
    Punteggio:
    18
    Sesso:
    Maschio
    Occupazione:
    Sviluppare web design (Studiare)
    Località:
    Udine
    Home Page:
    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($fh6);    //    legge 6 caratteri
            
    fseek($fh0);    //    torna a puntare il primo carattere del file ( il carattere 0 )
            
    $bytes8 fread($fh8);    //    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($bytes603) == "\xff\xd8\xff") return 'image/jpeg';            //    Immagini JPG
            
    if (substr($bytes602) == "\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($bytes604) == "\x49\x49\x2A\x00" || substr($bytes604) =="\x4D\x4D\x00\x2A") return 'image/tiff';        //    Immagini TIFF ( generalmente per i FAX )
            //    PDF
            
    if ($bytes6 == "%PDF" || substr($bytes604) == "\x25\x50\x44\x46") return 'application/pdf';        //    PDF
            //    ZIP, RAR file or 7z
            
    if (substr($bytes602) == "PK" || substr($bytes602) == "\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($bytes602) == "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/
     
Sto caricando...

Condividi questa Pagina