Bir dizenin Base64 kodlu olup olmadığını kontrol etme


195

Bir Base64 kodlu dize çözmek, sonra benim veritabanında saklamak istiyorum. Giriş Base64 kodlu değilse, bir hata atmam gerekiyor.

Bir dizenin Base64 kodlu olup olmadığını nasıl kontrol edebilirim?


Neden? Durum nasıl ortaya çıkabilir?
Lorne Marquis

2
hangi programlama dilini (ve / veya) İşletim Sistemini hedeflediğinizi belirtmeden, bu çok açık bir soru
bcarroll

5
Belirleyebileceğiniz tek şey, dizenin yalnızca base64 kodlu bir dize için geçerli olan karakterler içermesidir. Dizenin, bazı verilerin base64 kodlu sürümü olduğunu belirlemek mümkün olmayabilir. örneğin test1234geçerli bir base64 kodlu dizedir ve kodunu çözdüğünüzde bazı baytlar elde edersiniz. test1234Bir base64 kodlu dize olmadığı sonucuna varmak için uygulamadan bağımsız bir yol yoktur .
Kinjal Dixit

Yanıtlar:


249

Bir dizenin base64 kodlu olup olmadığını kontrol etmek için aşağıdaki normal ifadeyi kullanabilirsiniz:

^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$

Base64 kodlamasında karakter kümesi [A-Z, a-z, 0-9, and + /]. Kalan uzunluk 4'ten azsa, dize '='karakterlerle doldurulur .

^([A-Za-z0-9+/]{4})* dizenin 0 veya daha fazla base64 grubu ile başladığı anlamına gelir.

([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$Üç biçimden birini dize uçlarını şu anlama gelir: [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}=veya [A-Za-z0-9+/]{2}==.


10
Sadece doğrulamak istedim bu yüzden lütfen sorumla ilgili yardım edin: Bu normal ifadenin her zaman sadece base64 dizesini ifade edeceğinin garantisi nedir ?? Boşluğu olmayan herhangi bir dize varsa ve 4 karakterden daha fazla ise, bu dize base64 dizesi olarak kabul edilir ????
DShah

3
Sonra kodu çözülebilen geçerli bir base64 dizesidir. Minimum uzunluk kısıtlaması ekleyebilirsiniz; örneğin, dörtlü grupların sıfır veya daha fazla tekrarı yerine, dört ya da daha fazla (örneğin) gerektirir. Bu sizin probleminize de bağlıdır; kullanıcılarınız genellikle uzun kelimeler ve saf ASCII (Hawaii?) içeren bir dilde tek bir kelime girerse, base64 olmayan girişlerin genellikle boşluk, noktalama işareti vb. içerdiğinden daha hataya açıktır
üçlü

62
Bu yalnızca bir giriş olduğunu söylemek olabilirdi bir B64 kodlanmış değer, ancak giriş olup olmadığını söylemez olduğunu aslında bir B64 kodlanmış değer. Başka bir deyişle, abcdeşleşecek, ancak sadece düz bir abcdgirişin kodlanmış değerini temsil etmek zorunda değildir
Tzury Bar Yochay

3
Normal ifadeniz yanlış olduğundan, boş dizeyle eşleşmediğinden, RFC 4648'e göre sıfır uzunluklu ikili verilerin base64 kodlamasıdır.
kırmızımsı

5
@Adomas, "pass" o bayt dizisi içine şifresini çözer, mükemmel geçerli base64 dize 0xa5, 0xabve 0x2c. Karar vermek için daha fazla içeriğiniz yoksa neden bir a priori atın ?
Luis Colorado

52

Java kullanıyorsanız, aslında commons-codec kitaplığını kullanabilirsiniz

import org.apache.commons.codec.binary.Base64;

String stringToBeChecked = "...";
boolean isBase64 = Base64.isArrayByteBase64(stringToBeChecked.getBytes());

18
dokümantasyondan: isArrayByteBase64(byte[] arrayOctet)Kullanımdan kaldırıldı. 1.5 Kullanım isBase64(byte[]), 2.0'da kaldırılacaktır.
Avinash R

7
Ayrıca, kendiniz bayt dizisine dönüştürmek yerine Base64.isBase64 (String base64) kullanabilirsiniz.
Sasa

5
Ne yazık ki, belgelere dayanarak: commons.apache.org/proper/commons-codec/apidocs/org/apache/… : "Belirli bir Dizeyi , Base64 alfabesinde yalnızca geçerli karakterler içerip içermediğini görmek için test eder. geçerli." Bu, bu yöntemlerin "boşluk" veya sayılar ("0", "1") gibi bazı yanlış pozitifleri olduğu anlamına gelir.
Christian Vielma

String Base64.isBase64 (içerik)
ema

4
Bu yanıt yanlıştır, çünkü verilen bir Base64 kodlu değer olmasa bile stringToBeChecked="some plain text"ayarlanır boolean isBase64=true. Commons-codec-1.4 kaynağını okuyun, Base64.isArrayByteBase64()yalnızca dizedeki her karakterin Base64 kodlaması için geçerli olup olmadığını kontrol eder ve beyaz boşluğa izin verir.
Brad

49

Peki şunları yapabilirsiniz:

  • Uzunluğun 4 karakterin katları olduğunu kontrol edin
  • 0, 1 veya 2 '=' karakter olan dolgu hariç, her karakterin AZ, az, 0-9, +, / kümesinde olduğunu kontrol edin

Eğer o bekliyorsanız olacak base64 olmak için bir platform üzerine, o zaman muhtemelen sadece var olan her türlü kütüphane kullanabilirsiniz deneyin bir bayt dizisi bunu okumak için bu platforma göre değişiklik geçerli bir temel 64. değilse bir istisna atma, elbette.


Ayrıştırma, en azından kodu çözülmüş bayt dizisi için bellek gerektirmesi gerçeğiyle doğrulamadan farklıdır. Yani bu bazı durumlarda en etkili yaklaşım değildir.
Victor Yarema

1
@VictorYarema: Hem onaylama yaklaşımını (madde işaretleri) hem de ayrıştırma yaklaşımını (madde işaretleri noktalarından sonra) önerdim.
Jon Skeet

16

Java 8'den itibaren, dizeyi çözmek ve çözmek için java.util.Base64 komutunu kullanabilirsiniz :

String someString = "...";
Base64.Decoder decoder = Base64.getDecoder();

try {
    decoder.decode(someString);
} catch(IllegalArgumentException iae) {
    // That string wasn't valid.
}

3
evet, bu bir seçenek, ancak Java'da yakalamanın oldukça pahalı bir işlem olduğunu unutmayın
panser

2
Artık durum böyle değil. İstisna yönetimi oldukça iyi bir performans sergiliyor. Java Regex'in oldukça yavaş olduğunu unutmasanız iyi olur. Yani: GERÇEKTEN YAVAŞ! Bir Base64 kodunu çözmek ve String'i yukarıdaki Regex ile eşlemek yerine (çalışmadığını) kontrol etmek daha hızlıdır. Ben kaba bir test yaptım ve Java Regex eşleştirme kod çözme nihai bir istisna yakalamak daha yaklaşık altı kat daha yavaş (!!).
Sven Döring

Daha fazla test çalışması ile aslında on bir kat daha yavaştır. Java'da daha iyi bir Regex uygulaması zamanı. Java'daki Nashorn JavaScript motoruyla Regex kontrolü bile çok daha hızlıdır. Inanılmaz. Ayrıca JavaScript Regex (Nashorn ile) çok daha güçlüdür.
Sven Döring

3
Java 11 ile (Java 8 yerine) Regex denetimi 22 kat daha yavaştır. 🤦 (Çünkü Base64 kod çözme işlemi hızlandı.)
Sven Döring

15

PHP5 için böyle deneyin

//where $json is some data that can be base64 encoded
$json=some_data;

//this will check whether data is base64 encoded or not
if (base64_decode($json, true) == true)
{          
   echo "base64 encoded";          
}
else 
{
   echo "not base64 encoded"; 
}

PHP7 için kullanın

 //$string parameter can be base64 encoded or not

function is_base64_encoded($string){
 //this will check if $string is base64 encoded and return true, if it is.
 if (base64_decode($string, true) !== false){          
   return true;        
 }else{
   return false;
 }
}

1
Bu hangi dil? Soru bir dile başvurmadan soruldu
Özkan

bu işe yaramaz. docs Returns FALSE if input contains character from outside the base64 alphabet. base64_decode'u
Aley

1
Nasıl? giriş dış karakter içeriyorsa base64 değil, değil mi?
Suneel Kumar

7
var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
var isBase64Valid = base64Rejex.test(base64Data); // base64Data is the base64 string

if (isBase64Valid) {
    // true if base64 formate
    console.log('It is base64');
} else {
    // false if not in base64 formate
    console.log('it is not in base64');
}

5

Kontrol edin IF dize ait uzunluk Aftwerwards emin olmak için bu normal ifadeler kullanabilirsiniz 4. katları olan tüm karakterlerin dizede base64 karakterlerdir.

\A[a-zA-Z\d\/+]+={,2}\z

Kullandığınız kitaplık, satır başına maksimum 76 karakter kuralını gözlemleme yolu olarak yeni satır ekliyorsa, bunları boş dizelerle değiştirin.


Söz konusu bağlantıda 404 gösterilir. Lütfen kontrol edin ve güncelleyin.
Ankur

Maalesef @AnkurKumar, ancak insanların serin olmayan URL'leri olduğunda bunlar olur: sürekli değişir. Nereye taşındığı hakkında hiçbir fikrim yok. Umarım Google üzerinden başka faydalı kaynaklar bulabilirsiniz
Yaw Boakye

Web.archive.org'dan her zaman eski sayfalar alabilirsiniz - İşte orijinal URL. web.archive.org/web/20120919035911/http://… ya da metni buraya gönderdim: gist.github.com/mika76/d09e2b65159e435e7a4cc5b0299c3e84
Mladen Mihajlovic

4

Base64'in birçok çeşidi vardır , bu nedenle dizenizin işlemeyi beklediğiniz değişkene benzediğini belirlemeyi düşünün . Bu nedenle, endeks ve dolgu karakterlerine göre aşağıdaki regex ayarlamanız gerekebilir (örneğin +, /, =).

class String
  def resembles_base64?
    self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
  end
end

Kullanımı:

raise 'the string does not resemble Base64' unless my_string.resembles_base64?

3

Bunu dene:

public void checkForEncode(String string) {
    String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
    Pattern r = Pattern.compile(pattern);
    Matcher m = r.matcher(string);
    if (m.find()) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }
}

3

Bir dizenin base64 kodlu olup olmadığını kontrol etmek imkansızdır. Bu dizenin base64 kodlu dize biçiminde olup olmadığını doğrulamak mümkündür, bu da base64 kodlaması tarafından üretilen bir dize olabileceği anlamına gelir (dizenin bir regexp ile doğrulanabileceğini veya bir kütüphanenin kullanılabileceğini kontrol etmek için, birçok Bu sorunun diğer cevapları bunu kontrol etmek için iyi yollar sağlar, bu yüzden ayrıntılara girmeyeceğim).

Örneğin, dize flowgeçerli bir base64 kodlu dizedir. Ancak bunun basit bir dize mi, İngilizce bir kelime flowmi yoksa temel 64 kodlu dize mi olduğunu bilmek imkansızdır.~Z0


2
/^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/

Bu düzenli ifade raylarımda benim uygulama baz64 tanımlamak yardımcı oldu, ben sadece bir sorun vardı, o sadece bir dize uzunluğunu doğrulamak çözmek için "errorDescripcion" dizesini tanır, bir hata üretir.


Yukarıdaki normal ifade /^.....$/.match(my_string) 'Eşleşmeyen kapanış' diyerek biçimlendirme hatası veriyor)
james2611nov

Ve 'char-
class'ın

Nevermind her karakterin önüne \ ekleyerek düzeltildi.
james2611nov

errorDescriptionGeçerli bir base64 dize, o (hex) bayt ikili dizisi içine deşifre geçerli: 7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27.
Luis Colorado

Base64 kodlu dizesini kontrol etmek benim için mükemmel çalıştı.
Deepak Lakhara

1

Bu Python'da çalışır:

import base64

def IsBase64(str):
    try:
        base64.b64decode(str)
        return True
    except Exception as e:
        return False

if IsBase64("ABC"):
    print("ABC is Base64-encoded and its result after decoding is: " + str(base64.b64decode("ABC")).replace("b'", "").replace("'", ""))
else:
    print("ABC is NOT Base64-encoded.")

if IsBase64("QUJD"):
    print("QUJD is Base64-encoded and its result after decoding is: " + str(base64.b64decode("QUJD")).replace("b'", "").replace("'", ""))
else:
    print("QUJD is NOT Base64-encoded.")

Özet: IsBase64("string here") döner gerçek ise string hereBase64 ile kodlanmış olduğunu ve döner sahte eğer string hereBase64 kodlu DEĞİLDİ.


1

C # Bu harika bir performans sergiliyor:

static readonly Regex _base64RegexPattern = new Regex(BASE64_REGEX_STRING, RegexOptions.Compiled);

private const String BASE64_REGEX_STRING = @"^[a-zA-Z0-9\+/]*={0,3}$";

private static bool IsBase64(this String base64String)
{
    var rs = (!string.IsNullOrEmpty(base64String) && !string.IsNullOrWhiteSpace(base64String) && base64String.Length != 0 && base64String.Length % 4 == 0 && !base64String.Contains(" ") && !base64String.Contains("\t") && !base64String.Contains("\r") && !base64String.Contains("\n")) && (base64String.Length % 4 == 0 && _base64RegexPattern.Match(base64String, 0).Success);
    return rs;
}

1
Console.WriteLine("test".IsBase64()); // true
Langdon

2
Bir sorunu çözmek için programlama dilini değiştirmeyi tavsiye etmek genel olarak geçerli bir yanıt değildir.
Luis Colorado

0

Sisteminizdeki dizginin belirli bir sınırlaması veya kimliği olması dışında, dizeyi ve base64 kodlamasını ayırt etmenin bir yolu yoktur.


0

Bu snippet, orijinal içeriğin uzunluğunu bildiğinizde yararlı olabilir (örn. Bir sağlama toplamı). Kodlanmış formun doğru uzunlukta olup olmadığını kontrol eder.

public static boolean isValidBase64( final int initialLength, final String string ) {
  final int padding ;
  final String regexEnd ;
  switch( ( initialLength ) % 3 ) {
    case 1 :
      padding = 2 ;
      regexEnd = "==" ;
      break ;
    case 2 :
      padding = 1 ;
      regexEnd = "=" ;
      break ;
    default :
      padding = 0 ;
      regexEnd = "" ;
  }
  final int encodedLength = ( ( ( initialLength / 3 ) + ( padding > 0 ? 1 : 0 ) ) * 4 ) ;
  final String regex = "[a-zA-Z0-9/\\+]{" + ( encodedLength - padding ) + "}" + regexEnd ;
  return Pattern.compile( regex ).matcher( string ).matches() ;
}

0

RegEx çalışmazsa ve orijinal dizenin biçim stilini biliyorsanız, bu biçim için normal ifadeyi kullanarak mantığı tersine çevirebilirsiniz.

Örneğin base64 kodlu xml dosyalarıyla çalışıyorum ve dosyanın geçerli xml işaretlemesi içerip içermediğini kontrol ediyorum. Eğer kabul edemezse, base64 kodunun çözülmüş olduğunu varsayabilirim. Bu çok dinamik değil ama benim küçük uygulama için iyi çalışıyor.


0

Bu Python'da çalışır:

def is_base64(string):
    if len(string) % 4 == 0 and re.test('^[A-Za-z0-9+\/=]+\Z', string):
        return(True)
    else:
        return(False)

0

Daha önce bahsedilen bir normal ifadeyi kullanarak bunu deneyin:

String regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if("TXkgdGVzdCBzdHJpbmc/".matches(regex)){
    System.out.println("it's a Base64");
}

... Uzayları varsa Base64 olamaz gibi basit bir doğrulama da yapabiliriz:

String myString = "Hello World";
 if(myString.contains(" ")){
   System.out.println("Not B64");
 }else{
    System.out.println("Could be B64 encoded, since it has no spaces");
 }

Tamam, o zaman lütfen bir çözüm verebilir misiniz?
Marco

0

kod çözme işlemi sırasında ASCII karakterleri olan bir dize alırsak, dize kodlanmamışsa

(RoR) yakut çözeltisi:

def encoded?(str)
  Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count.zero?
end

def decoded?(str)
  Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count > 0
end

0

Bunu kullanmaya çalışıyorum, evet bu çalışıyor

^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$

ama en azından karakterin sonunun =

string.lastIndexOf("=") >= 0

Neden kontrol etmelisiniz =: Hangi özellikleri Base64kullanıyorsunuz? Ne anlama end of the charactergeliyor ve negatif olmayan bunu nasıl lastIndexOf()kontrol ediyor?
greybeard
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.