web-dev-qa-db-fra.com

Comment vérifier si une chaîne est base64 valide dans PHP

J'ai une chaîne et je veux tester avec PHP s'il s'agit d'un encodage base64 valide ou non.

48
Alias

Je réalise que c'est un sujet ancien, mais utiliser le paramètre strict ne va pas nécessairement aider.

L'exécution de base64_decode sur une chaîne telle que "Je ne suis pas codé en base 64" ne renverra pas la valeur false.

Si toutefois vous essayez de décoder la chaîne avec strict et de la recoder avec base64_encode, vous pouvez comparer le résultat avec les données d'origine pour déterminer s'il s'agit d'une valeur codée en base 64 valide:

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

Vous pouvez utiliser cette fonction:

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

Ce code devrait fonctionner, car la fonction de décodage renvoie FALSE si la chaîne n'est pas valide:

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

Vous pouvez en savoir plus sur la fonction base64_decode dans la documentation .

10
EdoDodo

Je pense que la seule façon de le faire est de faire un base64_decode() avec le paramètre $strict défini sur true et de voir s'il renvoie false.

6
Pekka 웃

Juste pour les chaînes, vous pouvez utiliser cette fonction, qui vérifie plusieurs propriétés en base64 avant de retourner true:

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;
}
4
merlucin

C’est une question très ancienne, mais j’ai trouvé que l’approche suivante était pratiquement irréprochable. Il prend également en compte ces chaînes étranges avec des caractères non valides qui provoqueraient une exception lors de la validation.

    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;
    }

}

J'ai eu l'idée de cette page et je l'ai adaptée à PHP.

2
Lucio Mollinedo

J'ai essayé ce qui suit:

  • base64 décode la chaîne avec le paramètre strict défini sur true.
  • base64 encoder le résultat de l'étape précédente. si le résultat n'est pas identique à la chaîne d'origine, la chaîne d'origine n'est pas encodée en base64
  • si le résultat est identique à la chaîne précédente, vérifiez si la chaîne décodée contient des caractères imprimables. J'ai utilisé la fonction php ctype_print pour vérifier les caractères non imprimables. La fonction renvoie false si la chaîne d'entrée contient un ou plusieurs caractères non imprimables.

Le code suivant implémente les étapes ci-dessus:

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;
}

Le code ci-dessus peut renvoyer des résultats inattendus. Par exemple, pour la chaîne "json", il retournera faux. "json" peut être une chaîne valide codée en base64 car son nombre de caractères est un multiple de 4 et tous les caractères sont dans la plage autorisée pour les chaînes codées en base64. Il semble que nous devions connaître la plage de caractères autorisés de la chaîne d'origine, puis vérifier si les données décodées contiennent ces caractères.

0
Nadir Latif

je sais que je pose une question très ancienne et j’ai essayé toutes les méthodes proposées; Je me retrouve finalement avec cette regex qui couvre presque tous mes cas:

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

en gros, je vérifie que tous les caractères ne sont pas imprimables (: graph :) n’est pas un espace ni une tabulation (\ s) et n’est pas une lettre unicode (tous les accents sont ex: èéùìà, etc.)

je reçois toujours des faux positifs avec ce caractère: £ § ° mais je ne les utilise jamais dans une chaîne et pour moi, c’est parfaitement correct de les invalider . J'agrège cette vérification avec la fonction proposée par @merlucin

alors le résultat:

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;
}
0
m47730

Vous pouvez simplement envoyer la chaîne via base64_decode (avec $ strict défini sur TRUE), il retournera FALSE si la saisie est invalide.

Vous pouvez également utiliser f.i. les expressions régulières voient si la chaîne contient des caractères extérieurs à l'alphabet base64 et vérifie si elle contient la bonne quantité de remplissage à la fin (= caractères). Mais utiliser simplement base64_decode est beaucoup plus facile et il ne devrait pas y avoir de risque qu'une chaîne malformée cause des dommages.

0
Wim

base64_decode () devrait retourner false si vos données codées en base64 ne sont pas valides.

0
Scoop

Vieux sujet, mais j'ai trouvé cette fonction et ça marche:

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;
}
0
Klian

Je code une solution pour valider des images en vérifiant la magie

$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";

Mais un moyen sûr consiste à utiliser Intervention

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