253 votes

À l’aide de .NET, comment pouvez-vous trouver que le type mime d’un fichier basé sur la signature de fichier pas l’extension

Je suis à la recherche d’un moyen simple d’obtenir un type mime où l’extension de fichier est incorrect ou non donné, quelque chose de semblable à cette question que dans .net.

178voto

Richard Gourlay Points 2289

J’ai utilisé urlmon.dll en fin de compte. J’ai pensé qu’il y aurait un moyen plus facile, mais cela fonctionne. J’inclus le code pour aider quelqu'un d’autre et me permettre de le retrouver si j’en ai besoin.

...

100voto

Anykey Points 779

J’ai trouvé une solution codé en dur, j’espère que je vais vous aider quelqu'un :

95voto

ROFLwTIME Points 2223

J'utilise le tableau d'octets séquences pour déterminer le type MIME d'un fichier donné. L'avantage de cette plus simplement en regardant l'extension de fichier le nom de fichier, c'est que si un utilisateur de renommer un fichier de contourner certains type de fichier restrictions de téléchargement, l'extension de nom de fichier ne parviendrait pas à attraper cette. D'autre part, l'obtention de la signature des fichiers via le tableau d'octets arrêtera cette espiègle comportement de se produire.

Voici un exemple en C#:

public class MimeType
{
    private static readonly byte[] BMP = { 66, 77 };
    private static readonly byte[] DOC = { 208, 207, 17, 224, 161, 177, 26, 225 };
    private static readonly byte[] EXE_DLL = { 77, 90 };
    private static readonly byte[] GIF = { 71, 73, 70, 56 };
    private static readonly byte[] ICO = { 0, 0, 1, 0 };
    private static readonly byte[] JPG = { 255, 216, 255 };
    private static readonly byte[] MP3 = { 255, 251, 48 };
    private static readonly byte[] OGG = { 79, 103, 103, 83, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 };
    private static readonly byte[] PDF = { 37, 80, 68, 70, 45, 49, 46 };
    private static readonly byte[] PNG = { 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82 };
    private static readonly byte[] RAR = { 82, 97, 114, 33, 26, 7, 0 };
    private static readonly byte[] SWF = { 70, 87, 83 };
    private static readonly byte[] TIFF = { 73, 73, 42, 0 };
    private static readonly byte[] TORRENT = { 100, 56, 58, 97, 110, 110, 111, 117, 110, 99, 101 };
    private static readonly byte[] TTF = { 0, 1, 0, 0, 0 };
    private static readonly byte[] WAV_AVI = { 82, 73, 70, 70 };
    private static readonly byte[] WMV_WMA = { 48, 38, 178, 117, 142, 102, 207, 17, 166, 217, 0, 170, 0, 98, 206, 108 };
    private static readonly byte[] ZIP_DOCX = { 80, 75, 3, 4 };

    public static string GetMimeType(byte[] file, string fileName)
    {

        string mime = "application/octet-stream"; //DEFAULT UNKNOWN MIME TYPE

        //Ensure that the filename isn't empty or null
        if (string.IsNullOrWhiteSpace(fileName))
        {
            return mime;
        }

        //Get the file extension
        string extension = Path.GetExtension(fileName) == null
                               ? string.Empty
                               : Path.GetExtension(fileName).ToUpper();

        //Get the MIME Type
        if (file.Take(2).SequenceEqual(BMP))
        {
            mime = "image/bmp";
        }
        else if (file.Take(8).SequenceEqual(DOC))
        {
            mime = "application/msword";
        }
        else if (file.Take(2).SequenceEqual(EXE_DLL))
        {
            mime = "application/x-msdownload"; //both use same mime type
        }
        else if (file.Take(4).SequenceEqual(GIF))
        {
            mime = "image/gif";
        }
        else if (file.Take(4).SequenceEqual(ICO))
        {
            mime = "image/x-icon";
        }
        else if (file.Take(3).SequenceEqual(JPG))
        {
            mime = "image/jpeg";
        }
        else if (file.Take(3).SequenceEqual(MP3))
        {
            mime = "audio/mpeg";
        }
        else if (file.Take(14).SequenceEqual(OGG))
        {
            if (extension == ".OGX")
            {
                mime = "application/ogg";
            }
            else if (extension == ".OGA")
            {
                mime = "audio/ogg";
            }
            else
            {
                mime = "video/ogg";
            }
        }
        else if (file.Take(7).SequenceEqual(PDF))
        {
            mime = "application/pdf";
        }
        else if (file.Take(16).SequenceEqual(PNG))
        {
            mime = "image/png";
        }
        else if (file.Take(7).SequenceEqual(RAR))
        {
            mime = "application/x-rar-compressed";
        }
        else if (file.Take(3).SequenceEqual(SWF))
        {
            mime = "application/x-shockwave-flash";
        }
        else if (file.Take(4).SequenceEqual(TIFF))
        {
            mime = "image/tiff";
        }
        else if (file.Take(11).SequenceEqual(TORRENT))
        {
            mime = "application/x-bittorrent";
        }
        else if (file.Take(5).SequenceEqual(TTF))
        {
            mime = "application/x-font-ttf";
        }
        else if (file.Take(4).SequenceEqual(WAV_AVI))
        {
            mime = extension == ".AVI" ? "video/x-msvideo" : "audio/x-wav";
        }
        else if (file.Take(16).SequenceEqual(WMV_WMA))
        {
            mime = extension == ".WMA" ? "audio/x-ms-wma" : "video/x-ms-wmv";
        }
        else if (file.Take(4).SequenceEqual(ZIP_DOCX))
        {
            mime = extension == ".DOCX" ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/x-zip-compressed";
        }

        return mime;
    }


}

L'avis que j'ai manipulé DOCX types de fichiers différemment depuis DOCX est vraiment juste un fichier ZIP. Dans ce scénario, j'ai tout simplement vérifier l'extension du fichier une fois que j'ai vérifié qu'il a de cette séquence. Cet exemple est loin d'être complète pour certaines personnes, mais vous pouvez facilement ajouter vos propres.

Si vous voulez ajouter plus de types MIME, vous pouvez obtenir le tableau d'octets séquences de beaucoup de différents types de fichiers à partir d'ici. Aussi, voici une autre bonne ressource concernant les signatures de fichiers.

Ce que je fais beaucoup de fois, si tout le reste échoue est l'étape par le biais de plusieurs fichiers d'un type particulier que je suis à la recherche pour et rechercher un motif dans la séquence d'octets des fichiers. En fin de compte, c'est toujours de vérification de base et ne peut être utilisé à 100% la preuve de la détermination des types de fichiers.

83voto

Steve Morgan Points 9296

Dans Urlmon.dll, il y a une fonction appelée FindMimeFromData.

À partir de la documentation

Le type MIME de détection, ou "détection de données," se réfère au processus de détermination d'un type MIME approprié à partir de données binaires. Le résultat final dépend d'une combinaison de serveur fourni type MIME les en-têtes, extension de fichier, et/ou les données elles-mêmes. Généralement, seuls les 256 premiers octets de données sont significatives.

Alors, lisez la suite de la première (jusqu'à) 256 octets dans le fichier et de le transmettre FindMimeFromData.

31voto

Bitmapped Points 379

Si vous utilisez .NET Framework 4.5 ou supérieur, il y a maintenant une méthode MimeMapping.GetMimeMapping(filename) qui retourne une chaîne avec le mappage de type Mime correct pour le nom de fichier passé.

La documentation est à http://msdn.microsoft.com/en-us/library/system.web.mimemapping.getmimemapping

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X