यदि इनपुट लंबाई 3 से विभाज्य नहीं है, तो बेस 64 एन्कोडिंग को पैडिंग की आवश्यकता क्यों है?


100

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

"एक अतिरिक्त पैड कैरेक्टर आवंटित किया गया है, जिसका उपयोग एन्कोडेड आउटपुट को 4 वर्णों के एक पूर्णांक में एकाधिक बल देने के लिए किया जा सकता है (या समतुल्य है जब unencoded बाइनरी टेक्स्ट 3 बाइट्स का एक से अधिक नहीं होता है), इन पैडिंग वर्णों को तब नष्ट कर दिया जाना चाहिए जब कोडिंग किया जाता है; अभी भी अनएन्कोडेड टेक्स्ट की प्रभावी लंबाई की गणना की अनुमति दें, जब इसके इनपुट बाइनरी की लंबाई 3 बाइट्स से अधिक नहीं होगी (अंतिम गैर-पैड चरित्र को सामान्य रूप से एन्कोड किया गया है ताकि अंतिम 6-बिट ब्लॉक का प्रतिनिधित्व शून्य हो जाए -अपने कम से कम महत्वपूर्ण बिट्स पर पैडेड, अधिकतर दो पैड अक्षर एन्कोडेड स्ट्रीम के अंत में हो सकते हैं) "।

मैंने एक प्रोग्राम लिखा जो किसी भी स्ट्रिंग को इनकोड और किसी भी बेस 64 एनकोडेड स्ट्रिंग को डीकोड कर सकता है। क्या समस्या हल करती है?

जवाबों:


208

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

हालांकि, पेडिंग उन स्थितियों में उपयोगी है जहां बेस 64 एन्कोडेड स्ट्रिंग्स को इस तरह से संक्षिप्त किया जाता है कि व्यक्तिगत अनुक्रमों की लंबाई खो जाती है, जैसा कि हो सकता है, उदाहरण के लिए, एक बहुत ही सरल नेटवर्क प्रोटोकॉल में।

अगर अनकैप्ड स्ट्रिंग्स को कंसीलर किया जाता है, तो मूल डेटा को पुनर्प्राप्त करना असंभव है क्योंकि प्रत्येक व्यक्तिगत अनुक्रम के अंत में विषम बाइट्स की संख्या के बारे में जानकारी खो जाती है। हालाँकि, यदि गद्देदार अनुक्रम का उपयोग किया जाता है, तो कोई अस्पष्टता नहीं है, और एक पूरे के रूप में अनुक्रम को सही ढंग से डिकोड किया जा सकता है।

संपादित करें: एक चित्रण

मान लीजिए कि हमारे पास एक कार्यक्रम है जो बेस 64-एनकोड करता है, उन्हें संक्षिप्त करता है और उन्हें एक नेटवर्क पर भेजता है। यह "I", "AM" और "TJM" को एन्कोड करता है, बिना पैडिंग के एक साथ परिणामों को सैंडविच करता है और उन्हें प्रसारित करता है।

  • Iकरने के लिए encodes SQ(SQ==गद्दी) के साथ
  • AMकरने के लिए encodes QU0( QU0=गद्दी) के साथ
  • TJMकरने के लिए encodes VEpN( VEpNगद्दी) के साथ

तो प्रेषित डेटा है SQQU0VEpN। रिसीवर बेस 64-डिकोड करता है जैसा I\x04\x14\xd1Q)कि इरादा था IAMTJM। परिणाम बकवास है, क्योंकि प्रेषक ने जानकारी को नष्ट कर दिया है जहां प्रत्येक शब्द एन्कोडेड अनुक्रम में समाप्त होता है। यदि प्रेषक ने SQ==QU0=VEpNइसके बजाय भेजा था , तो रिसीवर इसे तीन अलग-अलग बेस 64 अनुक्रमों के रूप में डीकोड कर सकता था जो देने के लिए सहमति देगा IAMTJM

पैडिंग से परेशान क्यों?

क्यों न केवल एक पूर्णांक लंबाई के साथ प्रत्येक शब्द को उपसर्ग करने के लिए प्रोटोकॉल डिज़ाइन करें? तब रिसीवर सही तरीके से स्ट्रीम को डिकोड कर सकता है और पैडिंग की कोई आवश्यकता नहीं होगी।

यह एक महान विचार है, जब तक हम जानते हैं डेटा की लंबाई हैं हम इसे एन्कोडिंग शुरू करने से पहले एन्कोडिंग कर रहे हैं। लेकिन क्या होगा अगर, शब्दों के बजाय, हम एक लाइव कैमरा से वीडियो के टुकड़े कर रहे थे? हम पहले से प्रत्येक चंक की लंबाई नहीं जानते होंगे।

यदि प्रोटोकॉल गद्दी का उपयोग करता है, तो लंबाई को प्रसारित करने की कोई आवश्यकता नहीं होगी। डेटा को एन्कोड किया जा सकता है क्योंकि यह कैमरे से आया था, प्रत्येक चंक को पैडिंग के साथ समाप्त किया गया था, और रिसीवर स्ट्रीम को सही ढंग से डिकोड करने में सक्षम होगा।

जाहिर है कि यह एक बहुत ही आकस्मिक उदाहरण है, लेकिन शायद यह बताता है कि क्यों गद्दी कुछ स्थितियों में सहायक हो सकती है।


22
+1 एकमात्र उत्तर जो वास्तव में "इसके अलावा एक उचित उत्तर भी प्रदान करता है" क्योंकि हम किसी न किसी कारण के लिए वाचालता और अतिरेक को पसंद करते हैं।
अवैध

1
यह उन विखंडू के लिए ठीक काम करता है जो अलग-अलग एन्कोडेड हैं, लेकिन डिकोडिंग के बाद अप्रत्यक्ष रूप से संक्षिप्त होने की उम्मीद है। यदि आप U0FNSQ == QU0 = भेजते हैं, तो आप वाक्य को फिर से जोड़ सकते हैं, लेकिन आप उन शब्दों को खो देते हैं जो वाक्य बनाते हैं। कुछ भी नहीं से बेहतर, मुझे लगता है। विशेष रूप से, GNU बेस 64 प्रोग्राम स्वचालित रूप से अतिक्रमित एन्कोडिंग को संभालता है।
मार्सेलो कैंटोस

2
क्या होगा यदि शब्दों की लंबाई 3 से अधिक थी? संघटन का यह गूंगा तरीका सूचना (शब्दों का अंत) को नष्ट करता है, न कि पैडिंग को हटाने का।
ग्रीनस्केप

2
बेस 64 कॉन्सेप्टेशन एनकोडर को बड़े आकार के चक्रों को तीन के एक से अधिक के साथ चंक आकारों को संरेखित करने के बिना समानांतर में संसाधित करने की अनुमति देता है। इसी तरह, एक कार्यान्वयन विवरण के रूप में, वहाँ एक एनकोडर हो सकता है जो एक आकार के आंतरिक डेटा बफर को फ्लश करने की आवश्यकता है जो तीन में से एक से अधिक नहीं है।
आंद्रे डी

1
यह उत्तर आपको यह सोचने पर मजबूर कर सकता है कि आप केवल डिकोडर को देकर "SQ == QU0 = VEpN" जैसा कुछ डिकोड कर सकते हैं। वास्तव में ऐसा लगता है कि आप नहीं कर सकते हैं, उदाहरण के लिए जावास्क्रिप्ट और php में कार्यान्वयन इसका समर्थन नहीं करते हैं। एक संक्षिप्त स्ट्रिंग के साथ शुरू, आपको या तो एक बार में 4 बाइट्स को डीकोड करना होगा या स्ट्रिंग को पैडिंग वर्णों के बाद विभाजित करना होगा। ऐसा लगता है कि उन क्रियान्वयनों में पैडिंग चार्ट्स की अनदेखी होती है, तब भी जब वे एक स्ट्रिंग के बीच में होते हैं।
रोमन

38

संबंधित नोट पर, आपके द्वारा बनाए गए मनमाने आधार रूपांतरण के लिए यहां एक आधार कनवर्टर है। का आनंद लें! https://convert.zamicol.com/

पैडिंग कैरेक्टर क्या हैं?

पैडिंग वर्ण लंबाई की आवश्यकताओं को पूरा करने में मदद करते हैं और कोई अर्थ नहीं रखते हैं।

पैडिंग का दशमलव उदाहरण: मनमानी आवश्यकता को देखते हुए सभी तार लंबाई में 8 वर्ण के होते हैं, संख्या 640 पूर्ववर्ती 0 के गद्दी पात्रों के रूप में इस आवश्यकता को पूरा कर सकती है क्योंकि वे कोई अर्थ नहीं रखते हैं, "00000640"।

बाइनरी एनकोडिंग

बाइट प्रतिमान: बाइट माप की वास्तविक मानक इकाई है और किसी भी एन्कोडिंग योजना को बाइट्स से संबंधित होना चाहिए।

Base256 इस प्रतिमान में बिल्कुल फिट बैठता है। एक बाइट बेस 256 में एक वर्ण के बराबर है।

Base16 , हेक्साडेसिमल या हेक्स, प्रत्येक वर्ण के लिए 4 बिट्स का उपयोग करता है। एक बाइट दो बेस 16 अक्षरों का प्रतिनिधित्व कर सकता है।

Base64 256 और बेस 16 के विपरीत बेस 64 बाइट प्रतिमान (और न ही बेस 32) में समान रूप से फिट नहीं होता है। सभी बेस 64 अक्षरों को एक पूर्ण बाइट से 6 बिट्स, 2 बिट्स में दर्शाया जा सकता है।

हम एक अंश के रूप में बाइट प्रतिमान बनाम base64 एन्कोडिंग का प्रतिनिधित्व कर सकते हैं: बाइट प्रति 8 बिट्स पर प्रति वर्ण 6 बिट्स । इस अंश को घटाकर 4 वर्णों पर 3 बाइट्स है।

यह अनुपात, प्रत्येक 4 बेस 64 अक्षरों के लिए 3 बाइट्स, वह नियम है जिसे हम बेस 64 को एन्कोडिंग करते समय फॉलो करना चाहते हैं। Base64 एन्कोडिंग केवल 3 बाइट बंडलों के साथ मापने का भी वादा कर सकती है, बेस 16 और बेस 25 के विपरीत जहां हर बाइट अपने आप खड़ी हो सकती है।

तो क्यों पैडिंग को प्रोत्साहित किया जाता है भले ही एन्कोडिंग पैडिंग पात्रों के बिना ठीक काम कर सके?

यदि किसी स्ट्रीम की लंबाई अज्ञात है या यदि डेटा स्ट्रीम समाप्त होने के समय यह जानना उपयोगी हो सकता है, तो पैडिंग का उपयोग करें। गद्दी वर्ण स्पष्ट रूप से संवाद करते हैं कि उन अतिरिक्त स्पॉट खाली होने चाहिए और किसी भी अस्पष्टता को नियंत्रित करते हैं। यहां तक ​​कि अगर लंबाई पैडिंग के साथ अज्ञात है, तो आपको पता चल जाएगा कि आपका डेटा स्ट्रीम कहां समाप्त होता है।

एक काउंटर उदाहरण के रूप में, JOSE जैसे कुछ मानक पैडिंग कैरेक्टर की अनुमति नहीं देते हैं। इस मामले में, यदि कोई चीज़ गायब है, तो एक क्रिप्टोग्राफ़िक हस्ताक्षर काम नहीं करेगा या अन्य गैर बेस 64 अक्षर गायब हो जाएंगे (जैसे "।")। हालाँकि लंबाई के बारे में धारणा नहीं बनाई गई है, इसलिए पैडिंग की ज़रूरत नहीं है क्योंकि अगर कुछ गड़बड़ है तो यह आसानी से काम नहीं करेगा।

और यह वही है जो base64 RFC कहता है,

कुछ परिस्थितियों में, आधार-एन्कोडेड डेटा में पैडिंग ("=") के उपयोग की आवश्यकता या उपयोग नहीं किया जाता है। सामान्य स्थिति में, जब ट्रांसपोर्ट किए गए डेटा के आकार के बारे में धारणा नहीं बनाई जा सकती है, तो सही डिकोड किए गए डेटा को पैडिंग करने की आवश्यकता होती है।

[...]

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

पैडिंग हमें खोए हुए बिट्स के वादे के साथ बेस 64 एनकोडिंग को डिकोड करने की अनुमति देता है। पैडिंग के बिना तीन बाइट बंडलों में मापने की स्पष्ट पावती नहीं है। पैडिंग के बिना आप मूल जानकारी के सटीक पुनरुत्पादन की सटीक गारंटी देने में सक्षम नहीं हो सकते हैं, आमतौर पर आपके स्टैक में कहीं और से टीसीपी, चेकसम या अन्य तरीकों की तरह।

उदाहरण

यहाँ RFC 4648 ( http://tools.ietf.org/html/rfc4648#s-/ ) का उदाहरण दिया गया है।

"BASE64" फ़ंक्शन के अंदर प्रत्येक वर्ण एक बाइट (base256) का उपयोग करता है। हम फिर बेस 64 में अनुवाद करते हैं।

BASE64("")       = ""           (No bytes used. 0%3=0.)
BASE64("f")      = "Zg=="       (One byte used. 1%3=1.)
BASE64("fo")     = "Zm8="       (Two bytes. 2%3=2.)
BASE64("foo")    = "Zm9v"       (Three bytes. 3%3=0.)
BASE64("foob")   = "Zm9vYg=="   (Four bytes. 4%3=1.)
BASE64("fooba")  = "Zm9vYmE="   (Five bytes. 5%3=2.)
BASE64("foobar") = "Zm9vYmFy"   (Six bytes. 6%3=0.)

यहाँ एक एनकोडर है जिसे आप साथ में खेल सकते हैं: http://www.motobit.com/util/base64-decoder-encoder.asp


16
-1 यह एक अच्छा और संपूर्ण पोस्ट है कि नंबर सिस्टम कैसे काम करता है, लेकिन यह बताता नहीं है कि जब एन्कोडिंग पूरी तरह से बिना काम करेगा तो पैडिंग का उपयोग क्यों किया जाता है।
मैटी विर्ककुनेन

2
क्या आपने भी प्रश्न पढ़ा है? आपको सही ढंग से डिकोड करने के लिए पैडिंग की आवश्यकता नहीं है।
नवीन

3
मुझे लगता है कि इस उत्तर ने वास्तव में यहां बताए गए कारण को स्पष्ट किया: "हम अब अतिरिक्त जानकारी के बिना मूल एन्कोडिंग के सटीक प्रजनन की गारंटी नहीं दे सकते हैं"। यह वास्तव में सरल है, गद्दी हमें बताती है कि हमें पूर्ण एन्कोडिंग प्राप्त हुई। हर बार जब आपके पास 3 बाइट्स होते हैं, तो आप सुरक्षित रूप से मान सकते हैं कि आगे बढ़ना और इसे डिकोड करना ठीक है, आप चिंता न करें, हम ... शायद एक और बाइट आने वाली है जो संभवतः एन्कोडिंग को बदल देगा।
डिडियर ए।

@DidierA। आपको कैसे पता चलेगा कि बेस 64 सबस्ट्रिंग में 3 और बाइट्स नहीं हैं? एक को डीकोड करने के लिए char*, आपको या तो स्ट्रिंग के आकार की जरूरत है या एक शून्य टर्मिनेटर की। गद्दी बेमानी है। इसलिए, ओपी का सवाल।
नवीन

4
@Navin यदि आप बेस 64 बाइट्स को डिकोड कर रहे हैं, तो आपको लंबाई नहीं पता है, 3 बाइट्स पैडिंग के साथ, आप जानते हैं कि हर बार जब आपको 3 बाइट्स मिलते हैं, तो आप 4 अक्षरों को प्रोसेस कर सकते हैं, जब तक आप स्ट्रीम के अंत तक नहीं पहुँचते। इसके बिना, आपको पीछे हटने की आवश्यकता हो सकती है, क्योंकि अगला बाइट पिछले चरित्र को बदलने का कारण बन सकता है, इसलिए यह बनाना कि आप केवल यह सुनिश्चित कर सकते हैं कि धारा के अंत तक पहुंचने के बाद आप इसे ठीक से डिकोड कर सकते हैं। तो, यह बहुत उपयोगी नहीं है, लेकिन इसमें कुछ किनारे मामले हैं जहां आप इसे चाहते हैं।
डिडियर ए।

1

आधुनिक दिन में इसका बहुत लाभ नहीं है। तो आइए इसे एक प्रश्न के रूप में देखें कि मूल ऐतिहासिक उद्देश्य क्या हो सकता है।

Base64 एन्कोडिंग RFC 1421 दिनांक 1993 में अपनी पहली उपस्थिति बनाता है । यह RFC वास्तव में एन्क्रिप्टिंग ईमेल पर केंद्रित है, और base64 एक छोटे खंड 4.3.2.4 में वर्णित है ।

यह RFC पैडिंग के उद्देश्य को स्पष्ट नहीं करता है। मूल उद्देश्य का उल्लेख करने के लिए निकटतम यह वाक्य है:

एक संदेश के अंत में एक पूर्ण एन्कोडिंग क्वांटम हमेशा पूरा होता है।

यह सहमति (यहां शीर्ष उत्तर) का सुझाव नहीं देता है, और न ही पैडिंग के स्पष्ट उद्देश्य के रूप में कार्यान्वयन में आसानी। हालांकि, पूरे विवरण को देखते हुए, यह मानना ​​अनुचित नहीं है कि यह डिकोडर 32-बिट इकाइयों ( "क्वांटा" ) में इनपुट को पढ़ने में मदद करने के उद्देश्य से किया गया है । आज इसका कोई फायदा नहीं है, हालांकि 1993 में असुरक्षित सी कोड ने वास्तव में इस संपत्ति का फायदा उठाया होगा।


1
पैडिंग की अनुपस्थिति में, दो तारों को समतल करने का प्रयास जब पहली स्ट्रिंग की लंबाई तीन से अधिक नहीं होती है, तो अक्सर एक प्रतीत होता है कि मान्य स्ट्रिंग होगी, लेकिन दूसरी स्ट्रिंग की सामग्री गलत तरीके से डिकोड होगी। पैडिंग को जोड़ना सुनिश्चित करता है कि नहीं होता है।
22 अक्टूबर को सुपरकाट

1
@ सुपरकैट यदि वह लक्ष्य होता, तो क्या हर बेस 64 स्ट्रिंग को केवल "=" के साथ समाप्त करना आसान नहीं होता? औसत लंबाई कम होगी, और यह अभी भी गलत संगति को रोक देगा।
रोमन स्टार्कोव

2
की औसत लंबाई b'Zm9vYmFyZm9vYg==' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy' b'Zm9vYmFyZm9vYmFyZg==' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v' के रूप में इस बात का एक ही है b'Zm9vYmFyZm9vYg=' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy=' b'Zm9vYmFyZm9vYmFyZg=' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v='
स्कॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.