Base64 डेटा पार्स या मान्य करने के लिए RegEx


99

क्या Base64 डेटा को मान्य या शुद्ध करने के लिए RegEx का उपयोग करना संभव है? यह आसान सवाल है, लेकिन इस सवाल को चलाने वाले कारक हैं जो इसे मुश्किल बनाते हैं।

मेरे पास एक बेस 64 डिकोडर है जो आरएफसी चश्मा का पालन करने के लिए इनपुट डेटा पर पूरी तरह से भरोसा नहीं कर सकता है। इसलिए, मैं जिन मुद्दों का सामना कर रहा हूं, वे शायद आधार 64 डेटा जैसे मुद्दे हैं जो 78 में टूट नहीं सकते हैं (मुझे लगता है कि यह 78 है, मुझे आरएफसी की दोहरी जांच करनी होगी, इसलिए सटीक संख्या गलत होने पर मुझे डिंग न करें) चरित्र लाइनें, या कि लाइनें CRLF में समाप्त नहीं हो सकती हैं; इसमें केवल एक सीआर, या एलएफ, या शायद नहीं हो सकता है।

तो, मैं एक समय के आधार के रूप में इस तरह से स्वरूपित Base64 डेटा पार्स करने का एक नरक था। इसके कारण, निम्नलिखित जैसे उदाहरण मज़बूती से समझाना असंभव हो जाते हैं। मैं केवल संक्षिप्त MIME हेडर्स को संक्षिप्तता के लिए प्रदर्शित करूंगा।

Content-Transfer-Encoding: base64

VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu

ठीक है, इसलिए कोई समस्या नहीं है, और वास्तव में हम उम्मीद करेंगे परिणाम है। और 99% मामलों में, किसी भी कोड का उपयोग करके कम से कम यह सत्यापित करें कि बफर में प्रत्येक चार एक वैध बेस 64 चार्ट है, पूरी तरह से काम करता है। लेकिन, अगले उदाहरण मिश्रण में एक रिंच फेंकता है।

Content-Transfer-Encoding: base64

http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu

Base64 एन्कोडिंग का यह संस्करण जो मैंने कुछ वायरस और अन्य चीजों में देखा है जो कुछ मेल पाठकों को हर कीमत पर माइम को पार्स करने की इच्छा का लाभ उठाने का प्रयास करते हैं, बनाम जो पुस्तक द्वारा सख्ती से चलते हैं, या आरएफसी; अगर तुम।

मेरा बेस 64 डिकोडर निम्नलिखित डेटा स्ट्रीम का दूसरा उदाहरण बताता है। और यहाँ ध्यान रखें, मूल धारा सभी ASCII डेटा है!

[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8

किसी के पास एक ही समय में दोनों समस्याओं को हल करने का एक अच्छा तरीका है? मुझे यकीन नहीं है कि यह संभव भी नहीं है, डेटा के दो अलग-अलग नियमों को लागू करने और परिणामों की तुलना करने पर। हालाँकि अगर आपने वह तरीका अपना लिया, तो आपको किस आउटपुट पर भरोसा है? ऐसा लगता है कि ASCII हेयुरेटिक्स सबसे अच्छे समाधान के बारे में है , लेकिन कितना अधिक कोड, निष्पादन समय, और जटिलता है कि वायरस स्कैनर के रूप में जटिल में कुछ जोड़ देगा, जो इस कोड वास्तव में शामिल है? आप यह जानने के लिए कि आधारभूत स्वीकार्य6464 क्या है, और क्या नहीं है, यह जानने के लिए आप ह्यूरिस्टिक्स इंजन को कैसे प्रशिक्षित करेंगे?


अपडेट करें:

इस प्रश्न को देखने के लिए संख्या को जारी रखें, मैंने सरल RegEx को पोस्ट करने का फैसला किया है जिसका उपयोग मैं 3 साल से C # एप्लिकेशन में कर रहा हूं, जिसमें सैकड़ों हजारों लेनदेन हैं। ईमानदारी से, मुझे गंबू द्वारा दिया गया उत्तर सबसे अच्छा लगता है, यही वजह है कि मैंने इसे चयनित उत्तर के रूप में चुना। लेकिन C # का उपयोग करने वाले किसी भी व्यक्ति के लिए, और कम से कम यह पता लगाने के लिए कि क्या एक स्ट्रिंग, या बाइट [] में वैध बेस 64 डेटा शामिल हैं या नहीं, बहुत जल्दी रास्ता खोज रहा है, मैंने पाया है कि मेरे लिए बहुत अच्छी तरह से काम करना है।

[^-A-Za-z0-9+/=]|=[^=]|={3,}$

और हां, यह बस बेस 64 डेटा के एक STRING के लिए है , RFC1341 संदेश को ठीक से फॉर्मेट नहीं किया गया है । इसलिए, यदि आप इस प्रकार के डेटा के साथ काम कर रहे हैं, तो कृपया उपरोक्त RegEx का उपयोग करने का प्रयास करने से पहले इसे ध्यान में रखें। यदि आप अन्य उद्देश्यों (URL, फ़ाइल नाम, XML एन्कोडिंग, आदि) के लिए Base16, Base32, Radix या यहां तक ​​कि Base64 के साथ काम कर रहे हैं, तो यह अत्यधिक अनुशंसा की जाती है कि आप RFC4648 पढ़ें जिसे गम्बो ने अपने उत्तर में उल्लिखित किया है, जो अच्छी तरह से होना चाहिए। इस प्रश्न / उत्तर सेट में सुझावों का उपयोग करने से पहले कार्यान्वयन द्वारा उपयोग किए जाने वाले चारसेट और टर्मिनेटरों के बारे में पता है।


मुझे लगता है कि आपको कार्य को बेहतर तरीके से परिभाषित करना होगा। यह पूरी तरह से अस्पष्ट है कि आपका उद्देश्य क्या है: सख्त हो? नमूने के 100% पार्स? ...
ADEpt

आप पहली बार उदाहरण होना चाहिए 'VGhpcyBpcyBhIHNpbXBsZSBBU0NJSSBCYXNlNjQgZXhhbXBsZSBmb3IgU3RhY2tPdmVyZmxvdy4 ='
JFS

अपनी भाषा में मानक समाधान का उपयोग क्यों न करें? रेगेक्स के आधार पर आपको हाथ से लिखे गए पार्सर की आवश्यकता क्यों है?
jfs

1
बड़ा सवाल है। हालाँकि मैंने UPDATE regex को एक बेस 64-एनकोडेड SHA के विरुद्ध चलाकर इसे NPM द्वारा वापस लाने की कोशिश की और यह विफल रहा जबकि चयनित उत्तर में regex ठीक काम करता है
जोश हबदास

1
सुनिश्चित नहीं हैं कि कैसे अद्यतन regex अभी भी सुधार के बिना पोस्ट किया जाता है, लेकिन यह लेखक की तरह लग रहा मतलब डाल करने के लिए ^कोष्ठक के बाहर, एक स्टार्ट-लंगर के रूप में। हालांकि, एक बेहतर रेगेक्स, बिना स्वीकार किए गए उत्तर के रूप में जटिल हो सकता है, होगा^[-A-Za-z0-9+/]*={0,3}$
kael

जवाबों:


147

से आरएफसी 4648 :

डेटा के बेस एन्कोडिंग का उपयोग कई स्थितियों में डेटा को स्टोर करने या स्थानांतरित करने के लिए किया जाता है, जो कि शायद विरासत कारणों से यूएस-एएसआईआईआई डेटा के लिए प्रतिबंधित हैं।

तो यह एन्कोडेड डेटा के उपयोग के उद्देश्य पर निर्भर करता है यदि डेटा को खतरनाक माना जाना चाहिए।

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

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

10
सत्यापन से पहले सभी व्हाट्सएप (जिसे RFC के अनुसार अनदेखा किया गया है) को हटाने का सबसे सरल उपाय होगा।
बेन ब्लैंक

2
पैडिंग के लिए अंतिम गैर-कैप्चरिंग समूह वैकल्पिक है।
गम्बू

4
पहले मुझे जटिलता पर संदेह था, लेकिन यह काफी हद तक मान्य है। यदि आप बस बेस 64-ईश से मिलान करना चाहते हैं, तो मैं ^ [a-zA-Z0-9 + /] = {0,3} $ करने के साथ आऊंगा, यह बेहतर है!
Lodewijk

3
@BogdanNechyporenko यह इसलिए nameहै क्योंकि (हेक्स) बाइट अनुक्रम का एक वैध Base64 एन्कोडिंग है 9d a9 9e
मार्टन

3
^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$बैकलैश से बचना चाहिए
खिजर

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

यह एक अच्छा है, लेकिन एक खाली स्ट्रिंग से मेल खाएगा

यह खाली स्ट्रिंग से मेल नहीं खाता:

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

2
खाली स्ट्रिंग अमान्य क्यों है?
जोश ली

8
यह नहीं। लेकिन अगर आप एक regex का उपयोग यह जानने के लिए कर रहे हैं कि क्या एक दिया गया तार आधार नहीं है या नहीं है, तो संभावना है कि आप रिक्त स्थान के इच्छुक नहीं हैं। कम से कम मुझे पता है कि मैं नहीं हूं।
njzk2

4
@LayZee: यदि आप ऐसा करते हैं, तो आप बेस 64 स्ट्रिंग को कम से कम 4-आकार के ब्लॉक में रखने के लिए बाध्य करते हैं, वैध मान प्रदान करते हैं जैसे कि MQ==आपकी अभिव्यक्ति के लिए मैच नहीं
njzk2

5
@ नर्स्लन और न ही यह होना चाहिए। यह एक वैध आधार 64 स्ट्रिंग नहीं है। (आकार 23 है, जो // 4 नहीं है)। AQENVg688MSGlEgdOJpjIUC=वैध रूप है।
njzk2

1
@JinKwon बेस 64 0, 1 या 2 के साथ समाप्त होता है =। अंतिम ?0 के लिए अनुमति देता है =। इसे {1}1 या 2 समाप्त करने की आवश्यकता है=
njzk2

4

न तो एक " : " और न ही एक " तक वैध Base64 में है, इसलिए मुझे लगता है कि आप स्पष्ट रूप से फेंक सकता दिखाएगा" http://www.stackoverflow.comलाइन। पर्ल में, कहते हैं, कुछ इस तरह

my $sanitized_str = join q{}, grep {!/[^A-Za-z0-9+\/=]/} split /\n/, $str;

say decode_base64($sanitized_str);

हो सकता है कि आप क्या चाहते हैं। यह उत्तपन करता है

यह StackOverflow निर्वासन के लिए सरल ASCII Base64 है।


मैं वहां सहमत हो सकता हूं, लेकिन URL के सभी अन्य अक्षर वैध आधार 64 के होते हैं ... तो, आप लाइन कहां बनाते हैं? बस लाइन ब्रेक पर? (मैंने उन लोगों को देखा है जहां लाइन के बीच में बस एक जोड़ी यादृच्छिक वर्ण हैं। बस उस वजह से, IMHO के बाकी लाइन को टॉस नहीं किया जा सकता है ...
लैरीएफ

@LarryF: जब तक आधार -64 एन्कोडेड डेटा पर अखंडता की जाँच नहीं होती है, तब तक आप यह नहीं बता सकते हैं कि डेटा के किसी भी आधार -64 ब्लॉक के साथ गलत वर्णों का क्या करना है। कौन सा सबसे अच्छा अनुमानी है: गलत पात्रों को अनदेखा करें (किसी भी और सभी को सही करने की अनुमति दें) या लाइनों को अस्वीकार करें, या बहुत अस्वीकार करें?
जोनाथन लेफ्लर 4

(जारी): संक्षिप्त उत्तर "यह निर्भर करता है" - जहां से डेटा आता है और जिस तरह की गड़बड़ आपको इसमें मिलती है।
जोनाथन लेफ्लर 4

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

3

सबसे अच्छा regexp जो मैं अब तक पा सकता था वह यहाँ है https://www.npmjs.com/package/base64-rexx

जो वर्तमान संस्करण में है जैसा दिखता है:

module.exports = function (opts) {
  opts = opts || {};
  var regex = '(?:[A-Za-z0-9+\/]{4}\\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)';

  return opts.exact ? new RegExp('(?:^' + regex + '$)') :
                    new RegExp('(?:^|\\s)' + regex, 'g');
};

शायद बिना बेहतर \\n?
जिन क्वोन

यह JSON स्ट्रिंग्स पर विफल हो जाएगा
idleberg

3

Base64 छवि को मान्य करने के लिए हम इस रेगेक्स का उपयोग कर सकते हैं

/ ^ डेटा: image / (?: gif | png | jpeg | bmp | webp):; ?; बेस 64, ((charset = utf-8?): [एक-zA-Z0-9] | [+ /] ) + = {0,2}

  private validBase64Image(base64Image: string): boolean {
    const regex = /^data:image\/(?:gif|png|jpeg|bmp|webp)(?:;charset=utf-8)?;base64,(?:[A-Za-z0-9]|[+/])+={0,2}/;
    return base64Image && regex.test(base64Image);
  }

0

यहाँ एक वैकल्पिक नियमित अभिव्यक्ति है:

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

यह निम्नलिखित स्थितियों को संतुष्ट करता है:

  • स्ट्रिंग की लंबाई चार की एक बहु होनी चाहिए - (?=^(.{4})*$)
  • सामग्री अल्फ़ान्यूमेरिक वर्ण या + या / होनी चाहिए [A-Za-z0-9+/]*
  • इसके अंत में दो पैडिंग (=) अक्षर हो सकते हैं - ={0,2}
  • यह खाली तारों को स्वीकार करता है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.