2010-03-31 46 views
23

有什麼方法可以檢測PHP中的字符串是否已經base64_encoded()?在PHP中檢測base64編碼?

我們正在將一些存儲從純文本轉換爲base64,部分存儲在需要更新的cookie中。如果文本尚未編碼,我想重置它們的Cookie,否則請保持獨立。

回答

24

對已經回答問題的延遲答覆抱歉,但我不認爲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Ǻ��ܡם" 

我認爲,除了嚴格的返回值檢查之外,您還需要進行後解碼驗證。最可靠的方法是,如果您可以解碼,然後檢查一組已知的可能值。

如果您檢查輸出以查看是否有許多超出正常範圍的utf-8(或其他任何編碼方式),那麼精度低於100%(對於較長的字符串更接近,對於短字符串不準確)使用)字符。

見這個例子:

<?php 
$english = array(); 
foreach (str_split('[email protected]#$%^*()_+|}?><": 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中可悲的是沒有內建的mean()。您使用什麼衡量標準(平均值,最大值等)與閾值(例如200)取決於您的估計使用情況。

總之,唯一的勝利舉動是不玩。我試圖避免首先分辨base64。

+0

令人沮喪... – catbadger 2017-03-13 18:37:37

3

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

16

我有同樣的問題,我結束了此解決方案:

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

唯一不好的地方就是我應該想到它第一;-) – chrishiestand 2013-07-08 22:56:11

+7

如果我做$ data ='iujhklsc'我得到有效,但它不是; – Mohit 2013-11-21 09:42:10

+0

我會檢查它.. – Amir 2013-11-22 10:35:28

6

我們可以將三個東西合併成一個函數來檢查給定的字符串是否是有效的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 (!base64_decode($string, true)) return false; 

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

    return true; 
} 
+0

我認爲「$ str」實際上應該是第二行的「$ string」。 – Wireblue 2016-08-31 01:40:04

+0

@Wireblue:謝謝我編輯$字符串$字符串 – 2016-09-08 07:21:13

+0

如果你不檢查輸入模塊長度4 == 0? – frumbert 2017-03-21 00:19:16

0

通常,base64中的文本沒有空格。

我用這個函數對我來說工作得很好。它測試字符串中的空格數是否小於1中的20。

例如:每個20個字符至少有1個空格---(空格/ strlen)< 0。05

function normalizaBase64($data){ 
    $spaces = substr_count ($data ," "); 
    if (($spaces/strlen($data))<0.05) 
    { 
     return base64_decode($data); 
    } 
    return $data; 
} 
1

如果輸入不是有效的base64編碼數據,base64_decode()將不會返回FALSE。使用imap_base64()相反,它如果$文本中包含的Base64字母以外的字符 imap_base64() Reference

9
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 

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

+0

這是非常有用的,但你的第四個例子 'is_base64_encoded(「a398UIhnj43f/1!+ sadfh3w84hduihhjw ==」); // true' 在我的測試中返回FALSE。 – Dylan 2017-09-12 01:16:10

0

可能這不是你問什麼了返回FALSE。但希望對某人有用。

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

感謝所有以前的答案作者在這個線程:)

0

這裏是我的解決方案:

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

如果解碼後的$string無效,則返回false,例如:「node」,「123」,「」等。