Détecter l'encodage base64 en PHP?
y a-t-il un moyen de détecter si une chaîne a été base64_encoded() dans PHP?
nous sommes en train de convertir du stockage de texte en base64 et une partie de celui-ci vit dans un cookie qui doit être mis à jour. J'aimerais réinitialiser leur cookie si le texte n'a pas encore été encodé, sinon laissez tomber.
11 réponses
excuses pour une réponse tardive à une question déjà répondue, mais je ne pense pas que base64_decode($x,true) soit une bonne solution pour ce problème. En fait, il se peut qu'il n'y ait pas de très bonne solution qui fonctionne contre un intrant donné. Par exemple, je peux mettre beaucoup de mauvaises valeurs dans $x et ne pas obtenir une fausse valeur de retour.
var_dump(base64_decode('wtf mate',true));
string(5) "���j�"
var_dump(base64_decode('This is definitely not base64 encoded',true));
string(24) "N���^~)��r��[jǺ��ܡם"
je pense qu'en plus de la stricte vérification de la valeur de retour, vous devrez également faire une validation post-décodage. La façon la plus fiable est si vous pouviez décoder et vérifier ensuite contre un ensemble de valeurs possibles.
une solution plus générale avec moins de 100% de précision (plus proche avec des chaînes plus longues, imprécis pour les chaînes courtes) est si vous vérifiez votre sortie pour voir si beaucoup sont en dehors d'une plage normale de caractères utf-8 (ou quel que soit l'encodage que vous utilisez).
par exemple:
<?php
$english = array();
foreach (str_split('az019AZ~~~!@#$%^*()_+|}?><": Iñtërnâtiônàlizætiøn') as $char) {
echo ord($char) . "\n";
$english[] = ord($char);
}
echo "Max value english = " . max($english) . "\n";
$nonsense = array();
echo "\n\nbase64:\n";
foreach (str_split(base64_decode('Not base64 encoded',true)) as $char) {
echo ord($char) . "\n";
$nonsense[] = ord($char);
}
echo "Max nonsense = " . max($nonsense) . "\n";
?>
Résultats:
Max value english = 195
Max nonsense = 233
Si vous pouvez faire quelque chose comme ceci:
if ( $maxDecodedValue > 200 ) {} //decoded string is Garbage - original string not base64 encoded
else {} //decoded string is useful - it was base64 encoded
Vous devriez probablement utilisez la moyenne () des valeurs décodées au lieu de la max (), j'ai juste utilisé max() dans cet exemple parce qu'il n'y a malheureusement pas de moyenne intégrée () dans PHP. Quelle mesure vous utilisez (moyenne,max, etc) par rapport à quel seuil (par exemple 200) dépend de votre profil d'utilisation estimé.
en conclusion, le seul coup gagnant est de ne pas jouer. Je voudrais essayer d'éviter d'avoir à discerner base64 en premier lieu.
j'ai eu le même problème, j'ai fini avec cette solution:
if ( base64_encode(base64_decode($data)) === $data){
echo '$data is valid';
} else {
echo '$data is NOT valid';
}
function is_base64_encoded($data)
{
if (preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $data)) {
return TRUE;
} else {
return FALSE;
}
};
is_base64_encoded("iash21iawhdj98UH3"); // true
is_base64_encoded("#iu3498r"); // false
is_base64_encoded("asiudfh9w=8uihf"); // false
is_base64_encoded("a398UIhnj43f/1!+sadfh3w84hduihhjw=="); // true
nous pouvons combiner trois choses en une seule fonction pour vérifier si une chaîne donnée est une base 64 valide encodée ou non.
function validBase64($string)
{
$decoded = base64_decode($string, true);
// Check if there is no invalid character in string
if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) return false;
// Decode the string in strict mode and send the response
if (!base64_decode($string, true)) return false;
// Encode and compare it to original one
if (base64_encode($decoded) != $string) return false;
return true;
}
j'étais sur le point de construire une base64 toggle en php, c'est ce que j'ai fait:
function base64Toggle($str) {
if (!preg_match('~[^0-9a-zA-Z+/=]~', $str)) {
$check = str_split(base64_decode($str));
$x = 0;
foreach ($check as $char) if (ord($char) > 126) $x++;
if ($x/count($check)*100 < 30) return base64_decode($str);
}
return base64_encode($str);
}
Il fonctionne parfaitement pour moi. Voici mes pensées complètes à ce sujet:http://www.albertmartin.de/blog/code.php/19/base64-detection
Et ici, vous pouvez essayer: http://www.albertmartin.de/tools
base64_decode () ne retournera pas FALSE si l'entrée n'est pas valide. Utilisez imap_base64()
à la place, il retourne FALSE si $text contient des caractères en dehors de l'alphabet de Base64
imap_base64() Référence
Habituellement, un texte en base64 n'a pas d'espaces.
j'ai utilisé cette fonction qui a bien fonctionné pour moi. Il teste si le nombre d'Espaces Dans la chaîne est inférieur à 1 sur 20.
E. g: au moins 1 espace pour chaque 20 caractères - - - (espaces / strlen) < 0.05
function normalizaBase64($data){
$spaces = substr_count ( $data ," ");
if (($spaces/strlen($data))<0.05)
{
return base64_decode($data);
}
return $data;
}
il est Peut-être pas exactement ce que vous avez demandé. Mais j'espère que ça sera utile pour quelqu'un.
dans mon cas, la solution était d'encoder toutes les données avec json_encode puis base64_encode.
$encoded=base64_encode(json_encode($data));
cette valeur peut être stockée ou utilisée selon vos besoins. Ensuite, pour vérifier si cette valeur n'est pas juste une chaîne de texte mais vos données encodées vous utilisez simplement
function isData($test_string){
if(base64_decode($test_string,true)&&json_decode(base64_decode($test_string))){
return true;
}else{
return false;
}
ou sinon
function isNotData($test_string){
if(base64_decode($test_string,true)&&json_decode(base64_decode($test_string))){
return false;
}else{
return true;
}
merci à toutes les réponses précédentes fil de discussion:)
Voici ma solution:
if(empty(htmlspecialchars(base64_decode($string, true)))) {
return false;
}
Elle retourne false si le décodé $string
n'est pas valide, par exemple: "nœud", "123", " ", etc.
votre meilleure option est:
$base64_test = mb_substr(trim($some_base64_data), 0, 76);
return (base64_decode($base64_test, true) === FALSE ? FALSE : TRUE);
Mieux vaut tard que jamais: Vous pourriez peut-être utiliser mb_detect_encoding()
pour savoir si la chaîne codée semble avoir été une sorte de texte:
function is_base64_string($s) {
// first check if we're dealing with an actual valid base64 encoded string
if (($b = base64_decode($s, TRUE)) === FALSE) {
return FALSE;
}
// now check whether the decoded data could be actual text
$e = mb_detect_encoding($b);
if (in_array($e, array('UTF-8', 'ASCII'))) { // YMMV
return TRUE;
} else {
return FALSE;
}
}