Есть ли способ определить, была ли строка base64_encoded () в PHP?
Мы конвертируем некоторое хранилище из обычного текста в base64, а часть его живет в файле cookie, который необходимо обновить. Я бы хотел сбросить их cookie, если текст еще не закодирован, иначе оставьте его в покое.
Извинения за поздний ответ на уже ответивший вопрос, но я не думаю, что base64_decode ($ x, true) является достаточно хорошим решением для этой проблемы. На самом деле не может быть очень хорошего решения, которое работает против любого заданного ввода. Например, я могу положить много плохих значений в $ x и не получить ложное возвращаемое значение.
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Ǻ ܡם"
Я думаю, что в дополнение к строгой проверке возвращаемого значения вам также нужно будет выполнить проверку после декодирования. Самый надежный способ – если вы можете декодировать, а затем проверить на известном наборе возможных значений.
Более общее решение с точностью менее 100% (ближе к более длинным строкам, неточным для коротких строк), если вы проверяете свой результат, чтобы увидеть, находятся ли многие из них вне нормального диапазона символов utf-8 (или любого другого, что вы используете).
См. Этот пример:
<?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"; ?>
Результаты:
Max value english = 195 Max nonsense = 233
Таким образом, вы можете сделать что-то вроде этого:
if ( $maxDecodedValue > 200 ) {} //decoded string is Garbage - original string not base64 encoded else {} //decoded string is useful - it was base64 encoded
Вероятно, вы должны использовать среднее значение () для декодированных значений вместо max (), я просто использовал max () в этом примере, потому что в PHP нет встроенного среднего (). Какую меру вы используете (средний, макс и т. Д.) Против того, какой порог (например, 200) зависит от вашего предполагаемого профиля использования.
В заключение, единственный победный ход – не играть. Я бы постарался не распознавать base64 в первую очередь.
У меня была та же проблема, я закончил с этим решением:
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
Мы можем объединить три вещи в одну функцию, чтобы проверить, является ли заданная строка допустимой базой 64, закодированной или нет.
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; }
Я собирался создать base64 для переключения в php, вот что я сделал:
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); }
Он отлично работает для меня. Вот мои полные мысли по этому поводу : http://www.albertmartin.de/blog/code.php/19/base64-detection
И здесь вы можете попробовать: http://www.albertmartin.de/tools
base64_decode () не вернет FALSE, если вход недействителен для кодированных данных base64. imap_base64()
этого используйте imap_base64()
, он возвращает FALSE, если $ text содержит символы вне алфавита Base64 imap_base64 () Ссылка
Обычно текст в base64 не имеет пробелов.
Я использовал эту функцию, которая отлично работала для меня. Он проверяет, имеет ли количество пробелов в строке меньше 1 в 20.
например: по крайней мере 1 место для каждых 20 символов — (пробелы / strlen) <0,05
function normalizaBase64($data){ $spaces = substr_count ( $data ," "); if (($spaces/strlen($data))<0.05) { return base64_decode($data); } return $data; }
Может быть, это не совсем то, о чем вы просили. Но надеюсь, что это будет полезно для кого-то.
В моем случае решение заключалось в кодировании всех данных с помощью json_encode, а затем base64_encode.
$encoded=base64_encode(json_encode($data));
это значение может быть сохранено или использовано независимо от того, что вам нужно. Затем, чтобы проверить, не является ли это значение не только текстовой строкой, но и ваши кодированные данные, вы просто используете
function isData($test_string){ if(base64_decode($test_string,true)&&json_decode(base64_decode($test_string))){ return true; }else{ return false; }
или альтернативно
function isNotData($test_string){ if(base64_decode($test_string,true)&&json_decode(base64_decode($test_string))){ return false; }else{ return true; }
Спасибо всем предыдущим авторам ответов в этой теме 🙂
Вот мое решение:
if(empty(htmlspecialchars(base64_decode($string, true)))) { return false; }
Он вернет false, если декодированная $string
недействительна, например: «node», «123», «» и т. Д.