2009-10-31 10 views

答えて

9

よく分かりませんが、おそらくmagic numbersについて調査する必要があります。

更新: これについて読むと、私はそれは非常に信頼できるとは思わない。

+1

として保存されたPDFは 'FindMimeData'でも' audio/mp3'のように何かを検出しないので、26種類以外のものを検出しているのであれば魔法の数字が唯一のオプションです。あなたはそれが信頼できないと思う理由を詳述できますか? – Mrchief

8

バイトストリームからはわかりませんが、最初にbyte[]を埋め込むときにMIMEタイプを保存できます。

+3

、 できません。しかし、ヒューリスティックを使ってマジックナンバーをチェックしたり、(UNIXの 'file'コマンドのように)良い確率でコンテンツタイプを推測することができます。そのソースを確認することができます。 –

+0

どうすればいいですか、ランドルフ? – AndreMiranda

+0

アップロードしたファイルをAttachment(難しいことではない)にキャストして、System.Net.MailのContentTypeで偽装することもできますし、この質問からURLMON.DLLハックを試すこともできます:http://stackoverflow.com/questions/58510/in-c-how-can-you-find-the-mime-of-file-of-the-file-signature-not-th –

7

短い答え:あなたは

長い答えはできません。通常、プログラムは、彼らが扱っているファイルの種類を知っているファイル拡張子を使用しています。その拡張子を持たない場合は、推測しかできません。たとえば、最初の数バイトを見て、よく知られているヘッダー(XML宣言タグ、ビットマップまたはJPEGヘッダーなど)を認識できるかどうかを確認します)。しかし、それは最終的にいつも推測になるでしょう:コンテンツに関するメタデータや情報がなければ、バイト配列は無意味です。

+0

良い例はすべてのファイルタイプzip/cabファイル(つまり.docx)をラップします。おそらく、もし私が単に拡張子を変更して別のプログラムでファイルを開くことができれば、基礎となるファイルバイトの「マジックナンバー」は同じになり、あいまいさにつながります。 – JoeBrockhaus

1

あなたはそうしたくありません。ファイルがアップロードされるときにPath.GetExtensionを呼び出し、バイト[]で拡張を渡します。

+0

どうすればいいですか? – AndreMiranda

+2

拡張子がファイル自体の内容であることをどのように確認できますか?すなわち、 JPG – user3308043

2

.rarファイル名に.gif拡張子を追加するだけで、 "some people"が初期のフリーイメージホスティングサイトで50MBのrarファイルを共有していたことを思い出させることができます。

パブリックに直面していて、特定のファイルタイプが予想されていて、それがそのファイルタイプであることを確認しなければならないことは明らかです。

一方、あなたのアプリケーションがアップロードされた拡張子やMIMEタイプを信用できない場合は、@rossfabircantと@RandolphPotterから受け取った回答のようにファイルがアップロードされたときに取得するだけです。 byte []と元の拡張子やmimetypeを持つ型を作成し、それを渡します。

ファイルが実際に有効な.jpegや.pngのような特定の予想されるタイプであることを確認する必要がある場合は、ファイルをそのタイプとして解釈し、正常に開くかどうかを確認できます。 (System.Drawing.Imaging.ImageFormat)

ファイルをバイナリコンテンツからのみ分類する場合、それは広い世界全体のフォーマットである可能性があります。これは実際には難しいオープンエンドの問題です。 100%信頼できる方法はありません。あなたはそれに対してTrIDを呼び出すことができますし、法執行機関の捜査官がそれらを見つけ出すことができれば類似の法医学ツールが存在する可能性があります。

難しいことでない場合は、しないでください。

+0

エッジケースに対する偉大な答え。 – user3308043

18

前述のように、MIMEマジックがこれを行う唯一の方法です。多くのプラットフォームでは、これを効率的に行うための最新かつ堅牢なMIMEマジックファイルとコードが提供されています。サードパーティのコードなしで.NETでこれを行う唯一の方法は、urlmon.dllのを使用することです。方法は次のとおりです。

public static int MimeSampleSize = 256; 

public static string DefaultMimeType = "application/octet-stream"; 

[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)] 
private extern static uint FindMimeFromData(
    uint pBC, 
    [MarshalAs(UnmanagedType.LPStr)] string pwzUrl, 
    [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer, 
    uint cbSize, 
    [MarshalAs(UnmanagedType.LPStr)] string pwzMimeProposed, 
    uint dwMimeFlags, 
    out uint ppwzMimeOut, 
    uint dwReserverd 
); 

public static string GetMimeFromBytes(byte[] data) { 
    try { 
     uint mimeType; 
     FindMimeFromData(0, null, data, (uint)MimeSampleSize, null, 0, out mimeType, 0); 

     var mimePointer = new IntPtr(mimeType); 
     var mime = Marshal.PtrToStringUni(mimePointer); 
     Marshal.FreeCoTaskMem(mimePointer); 

     return mime ?? DefaultMimeType; 
    } 
    catch { 
     return DefaultMimeType; 
    } 
} 

これはInternet Explorer MIME検出器を使用します。これは、アップロードされたファイルとともにMIMEタイプを送信するためにIEによって使用されるのと同じコードです。list of MIME types supported by urlmon.dllが表示されます。注意すべきことの1つは、非標準であるimage/pjpegimage/x-pngです。私のコードでは、これらをimage/jpegimage/pngに置き換えます。

+0

externメソッド宣言が間違っているようです。誰かがここに書きました:http://webandlife.blogspot.com/2012/11/google-is-your-alcoholic-friend.html – SandRock

+3

リファクタリング前のコードがリファクタリング後のコードとまったく同じであることは面白いです。他の人に間違いを指摘している人からはうまくいきませんが、明らかに自分自身でコピー/ペーストを処理することはできません。金田は彼の信用度が落ち着いていませんか? :) – Mrchief

+0

@Mrchielf:それは同じではありません。最初の違いは、 'uint'を' IntPtr'に変更したことです。なぜなら、ポストは特にCとC#のデータ型のマッチングの話題だったからです。 –

0

サポートしたいファイルタイプの数が限られている場合は、魔法の数字を使うことができます。

簡単な方法は、テキスト/ 16進エディタでサンプルファイルを開き、先頭のバイトを調べて、サポートされているセットからファイルを区別/破棄するために使用できるものがあるかどうかを調べることです。

一方、任意のファイルタイプを認識しようとしている場合は、ええ、みんながすでに述べたように、厳しいものです。

0

System.Drawing.Image 'RawFormat.Guid'プロパティを使用すると、イメージのMIMEタイプを検出できます。

他のファイルタイプの検索方法がわかりません。

http://www.java2s.com/Code/CSharp/Network/GetImageMimeType.htm

UPDATE:あなたはそれがSystem.Drawing.Image知っている場合は、あなたが行うことができます。この記事に

Using .NET, how can you find the mime type of a file based on the file signature not the extension

0

をご覧になることを試みることがあります。一般的には

public static string GeMimeTypeFromImageByteArray(byte[] byteArray) 
{ 
    using (MemoryStream stream = new MemoryStream(byteArray)) 
    using (Image image = Image.FromStream(stream)) 
    { 
     return ImageCodecInfo.GetImageEncoders().First(codec => codec.FormatID == image.RawFormat.Guid).MimeType; 
    } 
} 
関連する問題