PHP base64 kodlama algılar?

4 Cevap php

Bir dize PHP () base64_encoded olup olmadığını algılamak için bir yolu var mı?

Biz base64 düz metinden bazı depolama dönüştürme konum ve bunun bir parçası olarak güncellenmesi gerekiyor bir tanımlama yaşıyor. Ben başka türlü yalnız bırakın, metin henüz kodlanmış değil eğer onların kurabiye sıfırlamak istiyorum.

4 Cevap

giriş kodlanmış veri geçerli base64 değilse base64_decode () FALSE döndürür. Ayrıca önceden doğrulama için bir düzenli ifade düşünebiliriz, ama test etmek için büyük miktarlarda veri yoksa base64_decode yeterli olmalıdır. Doğal olarak, herhangi bir metin metin kodlanmış base64 gibi "bakmak", ama gereklerini yerine rasgele metin için olasılığı oldukça düşüktür.

Correction: karakter kümesi testi almak için, sıkı denetimini almak için base64_decode için ikinci argüman olarak true geçmesi gerekir. Ayrıca, katı modda da dolgu umurumda görünmüyor, bu yüzden base64 içeriği doğru yastıklı olması gerekiyordu kodlanmış ise de (uzunluğu dört bir çoklu olduğunu kontrol) kontrol etmek isteyebilirsiniz.

Zaten-cevap soruya geç bir yanıt için özür dilemek, ama ben base64_decode (true $ x), bu sorun için yeterince iyi bir çözüm olduğunu düşünmüyorum. Aslında, herhangi bir giriş karşı çalışan çok iyi bir çözüm olmayabilir. Örneğin, ben $ x içine kötü değerlerin sürü koymak ve yanlış bir dönüş değeri elde edemezsiniz.

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Ǻ��ܡם"

Ben sıkı bir dönüş değeri kontrole ek olarak, ayrıca post-decode doğrulama yapmak gerekir diye düşünüyorum. Eğer çözmek ve daha sonra olası değerler bilinen bir dizi karşı kontrol eğer en güvenilir yoludur.

Birçok utf-8 (veya ne olursa olsun kodlama kullanmak) bir karakter normal aralığın dışında olup olmadığını görmek için çıkış kontrol if (kısa dizeleri için yanlış uzun dizeleri ile daha yakın,) en az% 100 doğruluk ile daha genel bir çözümdür.

Bu örneğe bakın:

<?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";

?>

Sonuçlar:

Max value english = 195
Max nonsense = 233

Yani böyle bir şey olabilir:

if ( $maxDecodedValue > 200 ) {} //decoded string is Garbage - original string not base64 encoded

else {} //decoded string is useful - it was base64 encoded

PHP ne yazık ki hiçbir yerleşik ortalama () var çünkü muhtemelen yerine max deşifre değerlerin ortalamasını () () kullanmanız gerekir, ben sadece bu örnekte max () kullanılır. Eğer eşik (örn. 200) tahmini kullanım profiline bağlıdır şeye karşı (vb, max ortalama) kullanmak ne ölçüsüdür.

Sonuç olarak, sadece kazanan hareket oyun değildir. Ben ilk etapta base64 ayırt etmek zorunda kalmamak için denemek istiyorum.

Ben bu çözüm ile sona erdi, aynı sorun vardı:

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

Ben php base64 mafsal kurmak üzereydi, bu ben ne yaptım:

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

It works perfectly for me. Here are my complete thoughts on it: http://www.albertmartin.de/blog/code.php/19/base64-detection

Ve burada bunu deneyebilirsiniz: http://www.albertmartin.de/tools