2010-03-31 70 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”,“”等。