35

文字列が PHP で base64_encoded() されているかどうかを検出する方法はありますか?

一部のストレージをプレーン テキストから base64 に変換しており、その一部は更新が必要な Cookie に保存されています。テキストがまだエンコードされていない場合は Cookie をリセットしたいのですが、それ以外の場合はそのままにしておきます。

4

12 に答える 12

25

すでに回答済みの質問への回答が遅れたことをお詫びしますが、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() の代わりにデコードされた値の mean() を使用する必要があります。悲しいことに、PHP には組み込みの mean() がないため、この例では max() を使用しました。どのしきい値 (たとえば 200) に対してどの尺度 (平均値、最大値など) を使用するかは、推定使用プロファイルによって異なります。

結論として、唯一の勝利の手はプレーしないことです。そもそもbase64を見分ける必要がないようにします。

于 2011-04-12T08:05:03.140 に答える
25
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=="); // false

http://php.net/manual/en/function.base64-decode.php#81425

于 2016-01-24T22:03:50.647 に答える
23

私は同じ問題を抱えていましたが、最終的にこの解決策になりました:

if ( base64_encode(base64_decode($data)) === $data){
    echo '$data is valid';
} else {
    echo '$data is NOT valid';
}
于 2013-06-10T07:35:08.810 に答える
10

3 つのことを 1 つの関数に組み合わせて、指定された文字列が有効な Base 64 エンコードであるかどうかを確認できます。

function validBase64($string)
{
 $decoded = base64_decode($string, true);
 $result = false;
    
 // Check if there is no invalid character in string
 if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) {$result = false;}
        
 // Decode the string in strict mode and send the response
 if (!$decoded) {$result = false;}
        
 // Encode and compare it to original one
 if (base64_encode($decoded) != $string) {$result = false;}
        
 return $result;
}
于 2015-05-14T07:39:08.550 に答える
5

私はphpでbase64トグルを構築しようとしていました.これは私がしたことです:

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

于 2013-03-27T09:49:36.927 に答える
3

入力が有効な base64 エンコード データでない場合、base64_decode() は FALSE を返しません。imap_base64()代わりに使用してください。 $text に Base64 アルファベット以外の文字が含まれている場合は FALSE を返します imap_base64 () リファレンス

于 2015-11-20T11:29:48.963 に答える
1

それはあなたが求めたものではないかもしれません。しかし、それが誰かにとって役立つことを願っています。

私の場合、解決策は、すべてのデータを 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;
   }

このスレッドの以前のすべての回答作成者に感謝します:)

于 2016-02-08T11:38:22.263 に答える
0

通常、base64 のテキストにはスペースがありません。

私はこの機能を使用しましたが、これは私にとってはうまくいきました。文字列内のスペースの数が 20 分の 1 未満かどうかをテストします。

例: 20 文字ごとに少なくとも 1 つのスペース --- (スペース / strlen ) < 0.05

function normalizaBase64($data){
    $spaces = substr_count ( $data ," ");
    if (($spaces/strlen($data))<0.05)
    {
        return base64_decode($data);
    }
    return $data;
}
于 2015-11-09T14:34:56.120 に答える