source

PHP의 base64 문자열에서 이미지 유형 탐지

manysource 2023. 8. 8. 21:41

PHP의 base64 문자열에서 이미지 유형 탐지

PHP에서 base64 String으로 인코딩된 이미지의 유형을 찾을 수 있습니까?

원본 이미지 파일에 액세스할 방법이 없고 인코딩된 문자열만 있습니다.제가 본 바로는imagecreatefromstring()문자열 표현에서 이미지 리소스를 만들 수 있지만(base64에서 디코딩된 후) 이미지 유형을 자동으로 감지하고 이미지 리소스 자체가 특수 PHP 표현입니다.이미지를 다시 파일로 저장하려는 경우 저장하는 유형이 String 표현이 만들어진 원래 유형과 일치하는지 알 수 없습니다.

FileInfo는 다음과 같은 이점을 제공합니다.

$encoded_string = "....";
$imgdata = base64_decode($encoded_string);

$f = finfo_open();

$mime_type = finfo_buffer($f, $imgdata, FILEINFO_MIME_TYPE);

종속성 때문에 이러한 기능을 사용하지 않으려면 데이터의 첫 번째 바이트를 사용할 수 있습니다.

function getBytesFromHexString($hexdata)
{
  for($count = 0; $count < strlen($hexdata); $count+=2)
    $bytes[] = chr(hexdec(substr($hexdata, $count, 2)));
    
  return implode($bytes);
}

function getImageMimeType($imagedata)
{
  $imagemimetypes = array( 
    "jpeg" => "FFD8", 
    "png" => "89504E470D0A1A0A", 
    "gif" => "474946",
    "bmp" => "424D", 
    "tiff" => "4949",
    "tiff" => "4D4D"
  );
 
  foreach ($imagemimetypes as $mime => $hexbytes)
  {
    $bytes = getBytesFromHexString($hexbytes);
    if (substr($imagedata, 0, strlen($bytes)) == $bytes)
      return $mime;
  }
  
  return NULL;
}

$encoded_string = "....";
$imgdata = base64_decode($encoded_string);
$mimetype = getImageMimeType($imgdata);

references :- 여기서 파일 서명 목록을 확인합니다.

@Marc B가 제공한 솔루션이 저에게 가장 좋은 솔루션입니다(만약 우리의 php 버전이 5.3.0 이상이라면 그렇지 않으면 우리는 @Aaron Murgatroyd가 제공한 솔루션을 사용할 수 있습니다).

저는 이 해결책에 조금 더 추가하고 싶습니다.

다음과 같이 이미지 유형을 가져올 수 있습니다.

$split = explode( '/', $mime_type );
$type = $split[1]; 

사실, (모르는 경우) 이미지의 마임 유형은 다음과 같습니다. 이미지/유형 및 유형은 png, gif, jpeg 또는...

그것이 누군가를 도울 수 있기를 바라며 그의 해결책에 대해 @Marc B에게 감사합니다.

MIME 유형의 전체 목록은 여기에서 확인할 수 있습니다.

아래 코드는 마임 유형에서 이미지 유형을 가져옵니다.

<?php 
$base64 = "data:image/png;base64,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";

$image_info = getimagesize($base64);

$extension = (isset($image_info["mime"]) ? explode('/', $image_info["mime"] )[1]: "");

echo $extension;
 
?>

@Marc B가 보여주는 방식이 가장 좋습니다.

할까FInfo사용할 수 없습니다. 제가 아는 유일한 다른 방법은 데이터를 파일에 저장하고 실행하는 것입니다.getimagesize()그 위에

파일 형식 구조에 대해 최소한의 정보만 알고 있다면 어떤 유형의 파일인지 알아낼 수 있을 때까지 이론적으로 파일의 맨 위 바이트를 살펴볼 수 있습니다.

예를 들어, GIF 이미지는 항상 다음 바이트로 시작합니다.GIF89a파일의 시작 부분에서 해당 문자열을 찾을 수 있다면 GIF 이미지이며 다른 이미지 형식이 아님을 충분히 확인할 수 있습니다.(그러나 'GIF89a'로 시작하는 텍스트 파일일 수 있습니다. 절대적으로 확실하려면 더 많은 파일을 구문 분석해야 합니다.)

에는 "PNG 파일"이라는 .PNG시작에 거의 근접했습니다(처음에는 그렇지 않습니다. 다시 말하지만, 확실하게 하기 위해 얼마나 알아야 하는지 결정하는 데 도움이 되는 파일 형식 세부 사항을 조사해야 합니다.).

JPEG는 또한 헤더에 인식 가능한 문자열을 포함하지만, 이러한 문자열은 더 다양하고 복잡합니다.은 아마 " 은그끈조는것하좋것다입니을이심당신을▁string다니▁▁the"를 주의해야 할 입니다.Exif.

파일 형식 정의를 가져오면 더 정확해질 수 있지만, 정확해야 하는 정도에 따라 이진 편집기에서 일부 이미지 파일을 열어 파일 형식의 구조를 확인하는 것만으로도 파일 형식에 대해 충분히 알 수 있습니다.

이러한 리소스는 다음과 같은 이점을 제공합니다.

마법 번호를 사용하여 MIME 유형을 탐지할 수 있습니다(여기에서 파일 서명 목록을 확인하십시오).그러나 파일 서명은 100% 신뢰할 수 없으며 잘못된 긍정을 쉽게 발견할 수 있습니다.물론 그러한 해결책이 충분할 때 과제가 있습니다.

따라서 Base64 문자열이 있고 파일 서명을 사용하여 MIME 유형을 식별하려면 Base64를 디코딩할 필요가 없습니다.훨씬 빠른 방법은 파일 서명을 Base64로 저장하고 입력이 그 중 하나로 시작하는지 확인하는 것입니다.간단한 예:

<?php 

function detectMimeType(string $base64) 
{
    $signaturesForBase64 = [
        'JVBERi0'     => "application/pdf",
        'R0lGODdh'    => "image/gif",
        'R0lGODlh'    => "image/gif",
        'iVBORw0KGgo' => "image/png",
        '/9j/'        => "image/jpeg"
    ];
    
    foreach($signaturesForBase64 as $sign => $mimeType) 
    {
        if(strpos($base64, $sign) === 0) {
            return $mimeType;
        }
    }

    return false;
}

var_dump(detectMimeType('R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs=')); // image/gif
var_dump(detectMimeType('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC')); // image/png
var_dump(detectMimeType('JVBERi0xLjUKJYCBgoMKMSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvRmlyc3QgMTQxL04gMjAvTGVuZ3')); // application/pdf
var_dump(detectMimeType('/9j/4AAQSkZJRgABAQAAZABkAAD/2wCEABQQEBkSGScXFycyJh8mMi4mJiYmLj41NTU1NT5EQUFBQUFBRERERERERERE')); // image/jpeg

저는 이 Js Q-Answer에서 이 솔루션을 얻었습니다.


추가적으로: 이것도 제대로 작동합니다.

PHP를 따릅니다.NET 파일 정보 :-

$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
foreach (glob("*") as $filename) {
echo finfo_file($finfo, $filename) . "\n";
}
finfo_close($finfo);

언급URL : https://stackoverflow.com/questions/6061505/detecting-image-type-from-base64-string-in-php