簡體   English   中英

在 PHP 中檢測 base64 編碼?

[英]Detect base64 encoding in PHP?

有什么方法可以檢測字符串是否在 PHP 中是 base64_encoded() 嗎?

我們正在將一些存儲從純文本轉換為 base64,其中一部分位於需要更新的 cookie 中。 如果文本尚未編碼,我想重置他們的 cookie,否則不要管它。

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

對一個已經回答的問題的遲到回復表示歉意,但我認為 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

您可能應該使用解碼值的 mean() 而不是 max(),我在本示例中只使用了 max(),因為遺憾的是 PHP 中沒有內置 mean()。 您針對什么閾值(例如 200)使用什么度量(平均值、最大值等)取決於您估計的使用情況。

總而言之,唯一獲勝的舉動是不玩。 我會盡量避免首先識別base64。

我遇到了同樣的問題,我最終得到了這個解決方案:

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

遲到總比不到好:您可以使用mb_detect_encoding()來找出編碼的字符串是否似乎是某種文本:

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

我們可以將三件事組合成一個函數來檢查給定的字符串是否是有效的 base 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 (!$decoded) return false;

    // Encode and compare it to original one
    if (base64_encode($decoded) != $string) return false;

    return true;
}

我正要在 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

如果輸入不是有效的 base64 編碼數據,則 base64_decode() 將不會返回 FALSE。 改用imap_base64() ,如果 $text 包含 Base64 字母表之外的字符,則返回 FALSE imap_base64() 參考

這是我的解決方案:

if(empty(htmlspecialchars(base64_decode($string, true)))) { return false; }

如果解碼后的$string無效,它將返回 false,例如:“node”、“123”、“”等。

$is_base64 = function(string $string) : bool {
    $zero_one = ['MA==', 'MQ=='];
    if (in_array($string, $zero_one)) return TRUE;

    if (empty(htmlspecialchars(base64_decode($string, TRUE))))
        return FALSE;

    return TRUE;
};

var_dump('*** These yell false ***');
var_dump($is_base64(''));
var_dump($is_base64('This is definitely not base64 encoded'));
var_dump($is_base64('node'));
var_dump($is_base64('node '));
var_dump($is_base64('123'));
var_dump($is_base64(0));
var_dump($is_base64(1));
var_dump($is_base64(123));
var_dump($is_base64(1.23));

var_dump('*** These yell true ***');
var_dump($is_base64(base64_encode('This is definitely base64 encoded')));
var_dump($is_base64(base64_encode('node')));
var_dump($is_base64(base64_encode('123')));
var_dump($is_base64(base64_encode(0)));
var_dump($is_base64(base64_encode(1)));
var_dump($is_base64(base64_encode(123)));
var_dump($is_base64(base64_encode(1.23)));
var_dump($is_base64(base64_encode(TRUE)));

var_dump('*** Should these yell true? Might be edge cases ***');
var_dump($is_base64(base64_encode('')));
var_dump($is_base64(base64_encode(FALSE)));
var_dump($is_base64(base64_encode(NULL)));

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

可能這不是你所要求的。 但希望它對某人有用。

在我的情況下,解決方案是使用 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;
   }

感謝此線程中所有以前的答案作者:)

您最好的選擇是:

$base64_test = mb_substr(trim($some_base64_data), 0, 76);
return (base64_decode($base64_test, true) === FALSE ? FALSE : TRUE);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM