I have a string and want to test using PHP if it\'s a valid base64 encoded or not.
I think the only way to do that is to do a base64_decode() with the $strict
parameter set to true
, and see whether it returns false
.
Alright guys... finally I have found a bullet proof solution for this problem. Use this below function to check if the string is base64 encoded or not -
private function is_base64_encoded($str) {
$decoded_str = base64_decode($str);
$Str1 = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $decoded_str);
if ($Str1!=$decoded_str || $Str1 == '') {
return false;
}
return true;
}
Just for strings, you could use this function, that checks several base64 properties before returning 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;
}
base64_decode() should return false if your base64 encoded data is not valid.
You can just send the string through base64_decode
(with $strict set to TRUE), it will return FALSE if the input is invalid.
You can also use f.i. regular expressions see whether the string contains any characters outside the base64 alphabet, and check whether it contains the right amount of padding at the end (=
characters). But just using base64_decode is much easier, and there shouldn't be a risk of a malformed string causing any harm.
MOST ANSWERS HERE ARE NOT RELIABLE
In fact, there is no reliable answer, as many non-base64-encoded text will be readable as base64-encoded, so there's no default way to know for sure.
Further, it's worth noting that base64_decode will decode many invalid strings
For exmaple, and
is not valid base64 encoding, but base64_decode WILL decode it. As jw
specifically. (I learned this the hard way)
That said, your most reliable method is, if you control the input, to add an identifier to the string after you encode it that is unique and not base64, and include it along with other checks. It's not bullet-proof, but it's a lot more bullet resistant than any other solution I've seen. For example:
function my_base64_encode($string){
$prefix = 'z64ENCODEDz_';
$suffix = '_z64ENCODEDz';
return $prefix . base64_encode($string) . $suffix;
}
function my_base64_decode($string){
$prefix = 'z64ENCODEDz_';
$suffix = '_z64ENCODEDz';
if (substr($string, 0, strlen($prefix)) == $prefix) {
$string = substr($string, strlen($prefix));
}
if (substr($string, (0-(strlen($suffix)))) == $suffix) {
$string = substr($string, 0, (0-(strlen($suffix))));
}
return base64_decode($string);
}
function is_my_base64_encoded($string){
$prefix = 'z64ENCODEDz_';
$suffix = '_z64ENCODEDz';
if (strpos($string, 0, 12) == $prefix && strpos($string, -1, 12) == $suffix && my_base64_encode(my_base64_decode($string)) == $string && strlen($string)%4 == 0){
return true;
} else {
return false;
}
}