कैसे जांचें कि एक स्ट्रिंग बेस 64 एनकोडेड है या नहीं


194

मैं एक Base64 एन्कोडेड स्ट्रिंग को डीकोड करना चाहता हूं, फिर इसे मेरे डेटाबेस में संग्रहीत करें। यदि इनपुट बेस 64 एनकोडेड नहीं है, तो मुझे एक त्रुटि फेंकने की आवश्यकता है।

अगर स्ट्रिंग स्ट्रिंग बेस 64 एनकोडेड है तो मैं कैसे जांच सकता हूं?


क्यों? स्थिति कैसे पैदा हो सकती है?
लोर्न

2
यह निर्दिष्ट किए बिना कि आप किस प्रोग्रामिंग भाषा (और / या) ऑपरेटिंग सिस्टम को लक्षित कर रहे हैं, यह एक बहुत ही खुला प्रश्न है
bcarroll

5
आप यह निर्धारित कर सकते हैं कि स्ट्रिंग में केवल वे अक्षर हैं जो एक बेस 64 एन्कोडेड स्ट्रिंग के लिए मान्य हैं। यह निर्धारित करना संभव नहीं है कि स्ट्रिंग कुछ डेटा का आधार 64 एन्कोडेड संस्करण है। उदाहरण के test1234लिए एक वैध बेस 64 एन्कोडेड स्ट्रिंग है, और जब आप इसे डीकोड करते हैं तो आपको कुछ बाइट्स मिलेंगे। यह निष्कर्ष निकालने का कोई स्वतंत्र तरीका test1234नहीं है कि बेस 64 एनकोडेड स्ट्रिंग नहीं है।
किंजल दीक्षित

जवाबों:


249

यदि स्ट्रिंग एक बेस 64 एन्कोडेड है या नहीं, यह जांचने के लिए आप निम्नलिखित नियमित अभिव्यक्ति का उपयोग कर सकते हैं:

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

Base64 एन्कोडिंग में, वर्ण सेट है [A-Z, a-z, 0-9, and + /]। यदि बाकी की लंबाई 4 से कम है, तो स्ट्रिंग '='पात्रों के साथ गद्देदार है ।

^([A-Za-z0-9+/]{4})* इसका मतलब है कि स्ट्रिंग 0 या अधिक बेस 64 समूहों से शुरू होती है।

([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$तीन रूपों में से एक में स्ट्रिंग समाप्त होता है का अर्थ है: [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}=या [A-Za-z0-9+/]{2}==


10
बस यह सत्यापित करना चाहता था कि कृपया मेरे प्रश्न के साथ मदद करें: क्या गारंटी है कि यह रेगेक्स हमेशा केवल बेस 64 स्ट्रिंग को संदर्भित करेगा ?? यदि कोई स्ट्रिंग है जिसमें कोई स्थान नहीं है और यह 4 वर्णों में से एक है, तो क्या उस स्ट्रिंग को बेस 64 स्ट्रिंग माना जाएगा ????
डीएसएएच

3
फिर यह एक वैध बेस 64 स्ट्रिंग है जिसे डिकोड किया जा सकता है। आप एक न्यूनतम लंबाई की बाधा जोड़ सकते हैं; उदाहरण के लिए, चार के समूहों के शून्य या अधिक दोहराव के बजाय, चार (या अधिक) की आवश्यकता होती है। यह आपकी समस्या पर भी निर्भर करता है; यदि आपके उपयोगकर्ता अक्सर लंबे शब्दों और शुद्ध ASCII (हवाईयन) के साथ एक भाषा में एक ही शब्द दर्ज करते हैं, तो यह अधिक त्रुटि वाला है, यदि गैर-बेस 64 इनपुट में आमतौर पर रिक्त स्थान, विराम चिह्न, आदि शामिल हैं
21

62
यह केवल यह बताता है कि इनपुट b64 एन्कोडेड मान हो सकता है , लेकिन यह नहीं बताता कि इनपुट वास्तव में b64 एन्कोडेड मूल्य है या नहीं । दूसरे शब्दों में, abcdमेल खाएगा, लेकिन यह जरूरी नहीं है कि केवल एक सादे abcdइनपुट के एन्कोडेड मूल्य का प्रतिनिधित्व करें
टज़री बार योचाय

3
आपका regexp गलत है, क्योंकि यह खाली स्ट्रिंग से मेल नहीं खाता है, RFC 4648 के अनुसार शून्य-लंबाई बाइनरी डेटा का बेस 64 एन्कोडिंग है।
लाल करें।

5
@Adomas, "pass" एक पूरी तरह से वैध बेस 64 स्ट्रिंग है, जो बाइट्स के अनुक्रम में डिकोड करता है 0xa5, 0xabऔर 0x2c। यदि आप निर्णय लेने के लिए अधिक संदर्भ नहीं रखते हैं, तो इसे प्राथमिकता क्यों छोड़ें ?
लुइस कोलोराडो

50

यदि आप जावा का उपयोग कर रहे हैं, तो आप वास्तव में कॉमन्स-कोडेक लाइब्रेरी का उपयोग कर सकते हैं

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

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

17
प्रलेखन से: isArrayByteBase64(byte[] arrayOctet)पदावनत। 1.5 का उपयोग isBase64(byte[]), 2.0 में हटा दिया जाएगा।
अविनाश आर

7
आप इसे बाइट सरणी में कनवर्ट करने के बजाय Base64.isBase64 (स्ट्रिंग बेस 64) का भी उपयोग कर सकते हैं।
सास

5
अफसोस की बात है, प्रलेखन के आधार पर: commons.apache.org/proper/commons-codec/apidocs/org/apache/… : "किसी दिए गए स्ट्रिंग का परीक्षण यह देखने के लिए कि क्या इसमें बेस 64 वर्णमाला के भीतर केवल मान्य वर्ण हैं। वर्तमान में विधि व्हाट्सएप के रूप में व्यवहार करती है। वैध। " इसका मतलब यह है कि इस तरीके में कुछ गलत सकारात्मक हैं जैसे "व्हाट्सएप" या संख्याएं ("0", "1")।
क्रिश्चियन विल्मा

स्ट्रिंग के लिए Base64.isBase64 (सामग्री)
ema

4
यह उत्तर गलत है क्योंकि दिया गया है stringToBeChecked="some plain text"फिर boolean isBase64=trueभी यह सेट होता है, भले ही यह Base64 एनकोडेड वैल्यू न हो। कॉमन्स-कोडेक-1.4 के लिए स्रोत पढ़ें Base64.isArrayByteBase64()यह केवल यह जांचता है कि स्ट्रिंग में प्रत्येक वर्ण बेस 64 एन्कोडिंग के लिए विचार किया जाना वैध है और सफेद स्थान की अनुमति देता है।
ब्रैड

49

वैसे आप कर सकते हैं:

  • जांचें कि लंबाई 4 वर्णों की एक बहु है
  • जाँच करें कि हर वर्ण सेट में है AZ, az, 0-9, +, / सिवाय पैडिंग के अंत में जो 0, 1 या 2 '=' वर्ण है

यदि आप उम्मीद कर रहे हैं कि यह बेस 64 होगा , तो आप शायद बस अपने प्लेटफॉर्म पर उपलब्ध लाइब्रेरी का उपयोग कर सकते हैं इसे बाइट सरणी में डिकोड करने का प्रयास करें, अपवाद को फेंकना अगर यह वैध आधार 64 नहीं है। यह आपके प्लेटफॉर्म पर निर्भर करता है, बेशक।


पार्सिंग कम से कम इस तथ्य से मान्यता से अलग है कि इसे डिकोडेड बाइट सरणी के लिए मेमोरी की आवश्यकता होती है। तो यह कुछ मामलों में सबसे प्रभावी दृष्टिकोण नहीं है।
विक्टर यारेमा

1
@VictorYarema: मैंने दोनों को केवल एक सत्यापन दृष्टिकोण (बुलेट पॉइंट) और एक पार्सिंग दृष्टिकोण (बुलेट बिंदुओं के बाद) का सुझाव दिया।
जॉन स्कीट

16

जावा 8 के अनुसार, आप स्ट्रिंग को डिकोड और डिकोड करने के लिए बस java.util.Base64 का उपयोग कर सकते हैं :

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

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

3
हाँ, यह एक विकल्प है, लेकिन यह मत भूलो कि कैच जावा में काफी महंगा ऑपरेशन है
पृष्ठ

2
अब ऐसा नहीं है। अपवाद हैंडलिंग बहुत अच्छा प्रदर्शन कर रही है। आप बेहतर नहीं भूल जाते हैं कि जावा रेगेक्स बहुत धीमा है। मेरा मतलब है: वास्तव में धीमी! यह वास्तव में तेजी से एक बेस 64 को डिकोड करने और यह जांचने के लिए है कि उपरोक्त रेगेक्स के साथ स्ट्रिंग के मिलान के बजाय यह (नहीं) काम कर रहा है। मैंने एक मोटा परीक्षण किया और जावा रेगेक्स मिलान डिकोड पर एक अंतिम अपवाद को पकड़ने की तुलना में लगभग छह गुना धीमा (!!) है।
स्वेन डॉरिंग

अधिक टेस्ट रन के साथ यह वास्तव में ग्यारह गुना धीमा है। यह जावा में एक बेहतर रेगेक्स कार्यान्वयन का समय है। जावा में नैशॉर्न जावास्क्रिप्ट इंजन के साथ एक रेगेक्स चेक भी इतना तेज है। अविश्वसनीय। इसके अतिरिक्त जावास्क्रिप्ट रेगेक्स (नैशॉर्न के साथ) बहुत अधिक शक्तिशाली है।
स्वेन डोरिंग

3
जावा 11 (जावा 8 के बजाय) रेगेक्स चेक 22 गुना धीमा है। Base (क्योंकि बेस 64 डिकोडिंग तेज़ हो गई।)
स्वेन डोरिंग

15

PHP5 के लिए इस तरह का प्रयास करें

//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 के लिए इसका उपयोग करें

 //$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
यह कौनसी भाषा है? एक भाषा का उल्लेख किए बिना प्रश्न पूछा गया था
ओज़कॉन

यह काम नहीं करेगा। डॉक्स Returns FALSE if input contains character from outside the base64 alphabet. बेस 64_डॉब्लॉ पढ़े
एले

1
कैसे? यदि इनपुट में बाहर का चरित्र है तो यह बेस 64 नहीं है, है ना?
सुनील कुमार

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

देखने के लिए यदि स्ट्रिंग की लंबाई के 4. Aftwerwards सुनिश्चित करने के लिए इस regex का उपयोग एक से अधिक है सभी पात्रों स्ट्रिंग में बेस 64 अक्षर हैं।

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

यदि आप जिस लाइब्रेरी का उपयोग करते हैं, वह प्रति पंक्ति नियम में 76 अधिकतम वर्णों के अवलोकन के एक तरीके के रूप में एक नई पंक्ति जोड़ता है, तो उन्हें खाली तारों से बदल दें।


वर्णित लिंक 404 दिखाता है। कृपया जाँच करें और अपडेट करें।
अंकुर

क्षमा करें @AnkurKumar, लेकिन ऐसा तब होता है जब लोगों के पास अनचाहे URL होते हैं: वे हर समय बदलते रहते हैं। मुझे पता नहीं है कि इसे कहां स्थानांतरित किया गया है। मुझे आशा है कि आपको Google के माध्यम से अन्य उपयोगी संसाधन मिलेंगे
Yaw Boakye

आप हमेशा web.archive.org से पुराने पेज प्राप्त कर सकते हैं - यहाँ मूल यूआरएल है। web.archive.org/web/20120919035911/http://… या मैंने यहां पाठ पोस्ट किया है: gist.github.com/mika76/d09e2b65159e435e7a4cc4b0299c3e84
Mladen Mihajlovic

4

बेस 64 के कई वेरिएंट हैं , इसलिए केवल यह निर्धारित करने पर विचार करें कि क्या आपका स्ट्रिंग उस वेरिएंट जैसा दिखता है जिसे आप संभालने की उम्मीद करते हैं। इस तरह के रूप में, आप सूचकांक और गद्दी पात्रों के संबंध में नीचे regex समायोजित करना पड़ सकता (यानी +, /, =)।

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

उपयोग:

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

3

इसे इस्तेमाल करे:

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

यह जांचना असंभव है कि क्या एक स्ट्रिंग बेस 64 एनकोडेड है या नहीं। यह केवल तभी मान्य हो सकता है यदि वह स्ट्रिंग एक बेस 64 एनकोडेड स्ट्रिंग प्रारूप का हो, जिसका अर्थ यह होगा कि यह बेस 64 एन्कोडिंग द्वारा निर्मित एक स्ट्रिंग हो सकता है (यह जांचने के लिए, स्ट्रिंग को रेगेक्सपी के खिलाफ मान्य किया जा सकता है या लाइब्रेरी का उपयोग किया जा सकता है, कई इस प्रश्न के अन्य उत्तर इसे जांचने के अच्छे तरीके प्रदान करते हैं, इसलिए मैं विवरण में नहीं जाऊंगा)।

उदाहरण के लिए, स्ट्रिंग flowएक मान्य आधार 64 एन्कोडेड स्ट्रिंग है। लेकिन यह जानना असंभव है कि क्या यह केवल एक साधारण स्ट्रिंग है, एक अंग्रेजी शब्द है flow, या क्या यह आधार 64 एन्कोडेड स्ट्रिंग है~Z0


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

इस नियमित अभिव्यक्ति ने मुझे रेल में अपने आवेदन में बेस 64 की पहचान करने में मदद की, मुझे केवल एक ही समस्या थी, यह है कि यह स्ट्रिंग "एररड्रेसक्रिपशन" को पहचानता है, मैं एक त्रुटि उत्पन्न करता हूं, इसे हल करने के लिए बस एक स्ट्रिंग की लंबाई को मान्य करें।


उपरोक्त regex /^.....$/.match(my_string) 'बेजोड़ समापन) कहकर प्रारूपण त्रुटि देता है
james2611nov

और 'चार-वर्ग का समयपूर्व अंत: / ^ ((ए-ज़-ज़0-9 + /' वाक्यविन्यास त्रुटियों के साथ।
james2611nov

नेवरमाइंड ने इसे हर / वर्ण के सामने जोड़कर तय किया।
james2611nov

errorDescriptionएक वैध बेस 64 स्ट्रिंग है, यह बाइट्स के बाइनरी अनुक्रम में (हेक्स में) डिकोड करता है 7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27:।
लुइस कोलोराडो

इसके लिए मेरे लिए एकदम सही काम किया base64 एन्कोडेड स्ट्रिंग की जांच।
दीपक लखारा

1

यह पायथन में काम करता है:

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.")

सारांश: IsBase64("string here") रिटर्न सच अगर string hereBase64- एन्कोड है, और यह रिटर्न झूठी यदि string hereनहीं Base64- एन्कोड किया गया था।


1

C # यह शानदार प्रदर्शन कर रहा है:

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
लैंगडन

2
समस्या को हल करने के लिए प्रोग्रामिंग भाषा को स्विच करने की अनुशंसा सामान्य रूप से मान्य प्रतिक्रिया नहीं है।
लुइस कोलोराडो

0

अलग स्ट्रिंग और base64 को एन्कोड करने का कोई तरीका नहीं है, सिवाय इसके कि आपके सिस्टम में स्ट्रिंग की कुछ विशिष्ट सीमा या पहचान है।


0

जब आप मूल सामग्री की लंबाई (जैसे एक चेकसम) जानते हैं तो यह स्निपेट उपयोगी हो सकता है। यह जांचता है कि एन्कोडेड फॉर्म की लंबाई सही है।

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 काम नहीं करता है और आप मूल स्ट्रिंग की प्रारूप शैली जानते हैं, तो आप इस प्रारूप के लिए पुनः तर्क करके तर्क को उलट सकते हैं।

उदाहरण के लिए, मैं बेस 64 एनकोडेड xml फाइलों के साथ काम करता हूं और सिर्फ यह जांचता हूं कि फाइल में वैध xml मार्कअप है या नहीं। अगर ऐसा नहीं होता है तो मैं मान सकता हूं कि यह बेस 64 डिकोडेड है। यह बहुत गतिशील नहीं है, लेकिन मेरे छोटे अनुप्रयोग के लिए ठीक काम करता है।


0

यह पायथन में काम करता है:

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

0

पहले उल्लेखित रेगेक्स का उपयोग करके इसे आज़माएं:

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

... हम एक साधारण सत्यापन भी कर सकते हैं, जैसे अगर इसमें रिक्त स्थान हैं तो यह Base64 नहीं हो सकता है:

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

ठीक है, क्या आप कृपया एक समाधान दे सकते हैं?
मार्को १

0

यदि डिकोडिंग में हमें ASCII वर्णों के साथ एक स्ट्रिंग मिलती है, तो स्ट्रिंग को एन्कोड नहीं किया गया था

(RoR) रूबी समाधान:

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

मैं इसका उपयोग करने की कोशिश करता हूं, हां यह एक ऐसा काम है

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

लेकिन मैंने इस शर्त पर जोड़ा कि कम से कम चरित्र का अंत जांचने के लिए है =

string.lastIndexOf("=") >= 0

क्यों जाँचें =: आप किस विनिर्देशन का Base64उपयोग कर रहे हैं? क्या end of the characterमतलब है, और कैसे गैर-नकारात्मक lastIndexOf()जाँच करता है?
ग्रेबर्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.