Development Tip

PHP에서 문자열이 base64인지 확인하는 방법

yourdevel 2021. 1. 5. 19:42
반응형

PHP에서 문자열이 base64인지 확인하는 방법


문자열이 있고 유효한 base64 인코딩 여부를 PHP를 사용하여 테스트하고 싶습니다.


이것이 오래된 주제라는 것을 알고 있지만 strict 매개 변수를 사용하는 것이 반드시 도움이되는 것은 아닙니다.

"I am not base 64 encoding"과 같은 문자열에서 base64_decode를 실행하면 false가 반환되지 않습니다.

그러나 strict로 문자열을 디코딩하고 base64_encode로 다시 인코딩하면 결과를 원본 데이터와 비교하여 유효한 bas64 인코딩 값인지 확인할 수 있습니다.

if ( base64_encode(base64_decode($data, true)) === $data){
    echo '$data is valid';
} else {
    echo '$data is NOT valid';
}

이 기능을 사용할 수 있습니다.

 function is_base64($s)
{
      return (bool) preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s);
}

이 코드는 문자열이 유효하지 않은 경우 디코드 함수가 FALSE를 반환하므로 작동합니다.

if (base64_decode($mystring, true)) {
    // is valid
} else {
    // not valid
}

문서 에서 base64_decode 함수에 대한 자세한 내용을 읽을 수 있습니다 .


이를 수행하는 유일한 방법 base64_decode()$strict매개 변수를로 설정 true하고 반환 여부를 확인하는 것 false입니다.


문자열의 경우 true를 반환하기 전에 여러 base64 속성을 확인하는이 함수를 사용할 수 있습니다.

function is_base64($s){
    // Check if there are valid base64 characters
    if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s)) return false;

    // Decode the string in strict mode and check the results
    $decoded = base64_decode($s, true);
    if(false === $decoded) return false;

    // Encode the string again
    if(base64_encode($decoded) != $s) return false;

    return true;
}

이것은 정말 오래된 질문이지만 다음 접근 방식이 사실상 방탄이라는 것을 알았습니다. 또한 유효성 검사시 예외를 발생시키는 잘못된 문자가 포함 된 이상한 문자열도 고려합니다.

    public static function isBase64Encoded($str) 
{
    try
    {
        $decoded = base64_decode($str, true);

        if ( base64_encode($decoded) === $str ) {
            return true;
        }
        else {
            return false;
        }
    }
    catch(Exception $e)
    {
        // If exception is caught, then it is not a base64 encoded string
        return false;
    }

}

이 페이지 에서 아이디어를 얻어 PHP에 적용했습니다.


다음을 시도했습니다.

  • base64는 엄격한 매개 변수가 true로 설정된 문자열을 디코딩합니다.
  • base64는 이전 단계의 결과를 인코딩합니다. 결과가 원래 문자열과 동일하지 않으면 원래 문자열이 base64로 인코딩되지 않습니다.
  • 결과가 이전 문자열과 같으면 디코딩 된 문자열에 인쇄 가능한 문자가 포함되어 있는지 확인합니다. 인쇄 할 수없는 문자를 확인하기 위해 PHP 함수 ctype_print사용했습니다 . 입력 문자열에 인쇄 할 수없는 문자가 하나 이상 포함 된 경우이 함수는 false를 반환합니다.

다음 코드는 위의 단계를 구현합니다.

public function IsBase64($data) {
    $decoded_data = base64_decode($data, true);
    $encoded_data = base64_encode($decoded_data);
    if ($encoded_data != $data) return false;
    else if (!ctype_print($decoded_data)) return false;

    return true;
}

위의 코드는 예기치 않은 결과를 반환 할 수 있습니다. 예를 들어 "json"문자열의 경우 false를 반환합니다. "json"은 포함 된 문자 수가 4의 배수이고 모든 문자가 base64로 인코딩 된 문자열의 허용 범위에 있으므로 유효한 base64 인코딩 문자열 일 수 있습니다. 원래 문자열의 허용되는 문자 범위를 알고 디코딩 된 데이터에 해당 문자가 있는지 확인해야하는 것 같습니다.


이 방법이 내 프로젝트에서 완벽하게 작동한다고 씁니다. base64 Image를이 메서드에 전달할 때 유효하면 true를 반환하고 그렇지 않으면 false를 반환합니다. 시도하고 잘못된 것을 알려주십시오. 나는 기능에서 편집하고 배울 것입니다.

/**
 * @param $str
 * @return bool
 */
private function isValid64base($str){
    if (base64_decode($str, true) !== false){
        return true;
    } else {
        return false;
    }
}

base64_decode($ strict를 TRUE로 설정 한 상태에서) 문자열을 보낼 수 있으며 입력이 유효하지 않으면 FALSE를 반환합니다.

또한 fi 정규식을 사용하여 문자열에 base64 알파벳 이외의 문자가 포함되어 있는지 확인하고 끝에 적절한 양의 패딩이 포함되어 있는지 ( =문자) 확인할 수 있습니다. 그러나 base64_decode를 사용하는 것이 훨씬 쉬우 며 잘못된 문자열로 인해 해를 입힐 위험이 없어야합니다.


base64로 인코딩 된 데이터가 유효하지 않은 경우 base64_decode ()는 false를 반환해야합니다.


이전 주제이지만이 기능을 찾았으며 작동 중입니다.

function checkBase64Encoded($encodedString) {
$length = strlen($encodedString);

// Check every character.
for ($i = 0; $i < $length; ++$i) {
$c = $encodedString[$i];
if (
($c < '0' || $c > '9')
&& ($c < 'a' || $c > 'z')
&& ($c < 'A' || $c > 'Z')
&& ($c != '+')
&& ($c != '/')
&& ($c != '=')
) {
// Bad character found.
return false;
}
}
// Only good characters found.
return true;
}

i know that i resort a very old question, and i tried all of the methods proposed; i finally end up with this regex that cover almost all of my cases:

$decoded = base64_decode($string, true);
if (0 < preg_match('/((?![[:graph:]])(?!\s)(?!\p{L}))./', $decoded, $matched)) return false;

basically i check for every character that is not printable (:graph:) is not a space or tab (\s) and is not a unicode letter (all accent ex: èéùìà etc.)

i still get false positive with this chars: £§° but i never use them in a string and for me is perfectly fine to invalidate them. I aggregate this check with the function proposed by @merlucin

so the result:

function is_base64($s)
{
  // Check if there are valid base64 characters
  if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s)) return false;

  // Decode the string in strict mode and check the results
  $decoded = base64_decode($s, true);
  if(false === $decoded) return false;

  // if string returned contains not printable chars
  if (0 < preg_match('/((?![[:graph:]])(?!\s)(?!\p{L}))./', $decoded, $matched)) return false;

  // Encode the string again
  if(base64_encode($decoded) != $s) return false;

  return true;
}

I code a solution to validate images checking the sintaxy

$image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAABfVBMVEUAAAAxMhQAoIpFLCTimAE2IRs0IBodEg4OJyEAnYcAmoUAjnoALyn5rgNJLydEKyM5lWFFLCTuogI/JyBAKCHZnQoAlIAAkn48JR6fYgCIVACDUACPbAsAW06IWgAaDw0jFQscEQ4Am4XIfQDGewDhlwHelQEAi3gAe2oAd2cAXE8gFBAeEg8AVEgAtJwAsZn/vhMAuJ//xyMAu6BfQTf/wxv9wRlcPjVhQjj/vBBdQDb/xR9oSD1iRDlWOjH9xSL/uQr+twhkRTplRjxZPDPZpydILydAQD+pezNjRTNQNS3tuCZGLSX4sQn/tQTllgDhkgAArZUAqJFvTUD/wRgGtpp2m0aPaTl+azOIcjGkhS6OaS1ONCvNnirHmSrnsifHnSfFjyemfCfcqSa/jyLwuR/ptB/MmRxiPhnpqRX1sxHzqwnCfgb+tQTYjALnmQH2qQDzpQDejgAnsYQnsYNwTkBlRTtfQi9eQS+1kCy2kSuFYSuEYSvkpRfrqxQPeVhkAAAALnRSTlMADPz0qnhzNBPry5kH/vr36ubKxLy4sKmifVVNQT84Ih4Y2aWloqKMgHdJPDwse8ZSvQAAAbVJREFUOMuV0uVzggAYx3Gsbca6u3vDqSDqBigD25nrLrvX+bfvMSeId9vnBXD3+97zCuQ/ZhUDvV1dvQOKWfFdIWOZHfDMyhRi+4ibZHZLwS5Dukea97YzzAQFYEgTdtYm3DtkhAUKkmFI0mTCCFmH8ICbsEBRhmEWwi080U+xBNwApZlgqX7+rummWJcLEkAQLhdLdWt4wbSXOqX1Hu784uKc8+jpU8o7zQva7RSnb8BR9nZesGF/oelLT2X1XNL0q31dcOGDPnwKO7eBMxw+pD8FF2a8N9vcyfttKbh9O+HwG+8MLxiL3+FXDsc9Du4djiv8Lj7GC0bTMTx6dGzEgfH4KIrH0qO8YDyQjESMvyLJwDjCs5DaKsvlzOV3ah4RkFcCM+wlckRoymcG107ntRn4ppAmSzar9Tvh830lrFbbItJM0meDBcCzT4KIFfLOzB7IdMphFzUxWMjnC4MToqNkbWVY1RPw+wM9quHVSY1gnhyShlCd4aHo9xcfDTptSKnebPxjh0Kooewgmz2ofKFStaS+z2l1Nfv79c+gqlaog6io4HI1UKItKKuBVNuCFPmDH12fd4lDaGbkAAAAAElFTkSuQmCC';
$allowedExtensions = ['png', 'jpg', 'jpeg'];

// check if the data is empty
if (empty($image)) {
    echo "Empty data";
}

// check base64 format
$explode = explode(',', $image);
if(count($explode) !== 2){
    echo "This string isn't sintaxed as base64";
}
//https://stackoverflow.com/a/11154248/4830771
if (!preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $explode[1])) {
    echo "This string isn't sintaxed as base64";
}

// check if type is allowed
$format = str_replace(
        ['data:image/', ';', 'base64'], 
        ['', '', '',], 
        $explode[0]
);
if (!in_array($format, $allowedExtensions)) {
    echo "Image type isn't allowed";
}
echo "This image is base64";

But a safe way is using Intervention

use Intervention\Image\ImageManagerStatic;
try {
    ImageManagerStatic::make($value);
    return true;
} catch (Exception $e) {
    return false;
}

If data is not valid base64 then function base64_decode($string, true) will return FALSE.


I am using this approach. It expects the last 2 characters to be ==

substr($buff, -2, 1) == '=' && substr($buff, -1, 1) == '=')

업데이트 : 위의 항목이 실패하면 다른 확인을 마쳤습니다 .base64_decode ($ buff, true)

참조 URL : https://stackoverflow.com/questions/4278106/how-to-check-if-a-string-is-base64-valid-in-php

반응형