2009-10-31 4 views

답변

9

확실하지 않지만 어쩌면 magic numbers에 대해 조사해야합니다.

업데이트 : 그것에 대해 읽고, 나는 매우 안정적이라고 생각하지 않습니다.

+1

으로 저장된 PDF는'FindMimeData'는'audio/mp3'처럼 기본적인 것을 감지하지 못하기 때문에, 26 가지 유형 밖에서 뭔가를 발견한다면 마법의 숫자 만이 유일한 옵션입니다. 믿을 수없는 이유에 대해 자세히 설명해 주시겠습니까? – Mrchief

8

바이트 스트림에서 알 수는 없지만 처음에 byte[]을 채울 때 MIME 형식을 저장할 수 있습니다.

+3

, 당신은 할 수 없습니다. 그러나, 휴리스틱을 사용하여 매직 넘버를 확인하고 좋은 확률로 컨텐츠 유형을 추측 할 수 있습니다 (UNIX의'file' 명령과 동일). 소스를 확인할 수 있습니다. –

+0

어떻게해야합니까, Randolph? – AndreMiranda

+0

업로드 된 파일을 첨부 파일 (첨부 파일)에 캐스팅하여 System.Net.Mail의 ContentType을 사용하여 가짜 파일을 만들거나 URLMON.DLL 해킹을 시도 할 수 있습니다. http://stackoverflow.com/questions/58510/in-c-how-can-you-find-the-mime-of-a-file-on-the-file-signature-not-th –

7

짧은 답변 : 당신이

긴 대답은 없습니다 : 일반적으로, 프로그램들이 다루고있는 파일의 유형을 알고 파일 확장자를 사용합니다. 그 확장자가 없다면 추측 만 할 수 있습니다 ... 예를 들어, 처음 몇 바이트를 살펴보고 잘 알려진 헤더 (예 : XML 선언 태그 또는 비트 맵 또는 JPEG 헤더). 그러나 그것은 결국 추측 일 것입니다. 내용에 관한 메타 데이터 나 정보가 없으면, 바이트 배열은 의미가 없습니다 ...

+0

좋은 예는 모든 파일 형식 일 수 있습니다 그 포장 우편/택시 파일 (즉,. docx). 아마 확장을 변경하고 다른 프로그램으로 파일을 열 수 있다면, 기본 파일 바이트에 대한 '매직 넘버'는 동일 할 것이므로 모호한 것으로 이끈다. – JoeBrockhaus

1

그렇게하고 싶지는 않습니다. 파일을 업로드 할 때 Path.GetExtension을 호출하고 바이트 []를 사용하여 확장을 전달합니다.

+0

어떻게하면됩니까? – AndreMiranda

+2

확장 프로그램이 파일 자체의 내용인지 어떻게 확인할 수 있습니까? 즉. JPG – user3308043

2

.rar 파일 이름에 .gif 확장자를 추가하여 초기 무료 이미지 호스팅 사이트에서 "일부 사용자"가 50MB rar 파일을 공유하는 것을 생각 나게합니다.

공개적으로 직면하고 특정 파일 형식을 예상하고 파일 형식이 맞는지 확인해야하는 경우 분명히 확장명을 신뢰할 수 없습니다.

반면에 앱이 업로드 된 확장자 및/또는 MIME 유형을 불신하지 않을 경우 @rossfabircant 및 @RandolphPotter에서받은 답변처럼 파일 업로드시 가져 오기만하면됩니다. 원래의 확장자 또는 mimetype뿐만 아니라 byte []가있는 유형을 생성하고이를 전달하십시오.

파일이 실제로 유효한 .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을 볼 수 있습니다. 조심해야 할 것은 비표준 인 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

에 모습을 복용하려고 할 수 있습니다, 당신이 할 수 있습니다 : 일반적으로

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; 
    } 
} 
관련 문제