हिन्दी

डेवलपर टूल · Base64 एनकोडर और डिकोडर

JSON APआई में Base64: बाइनरी फ़ील्ड एन्कोडेड क्यों होते हैं और इसकी आपको क्या कीमत चुकानी पड़ती है

· यह क्यों मायने रखती है

Base64 एन्कोडिंग

एक JSON फ़ील्ड जिसमें परिवहन के लिए एन्कोड किए गए बाइनरी डेटा का प्रतिनिधित्व करने वाली लंबी Base64 स्ट्रिंग है
मूल ToolAcre वेक्टर चित्रण

JSON में कोई बाइट प्रकार नहीं है, इसलिए बाइनरी डेटा आमतौर पर एक स्ट्रिंग में Base64-एन्कोडेड होता है। यह पोस्ट बताती है कि वह कन्वेंशन क्यों मौजूद है, आकार और CPU में इसकी लागत क्या है, और जब एक अलग बाइनरी एंडपॉइंट बेहतर कॉल होता है।

PDF फ़ील्ड जो प्रतिक्रिया पर हावी रही - एक ठोस API पेलोड जहां एक Base64 ब्लॉब बाकी सभी चीज़ों से अधिक है

API प्रतिक्रिया में एकल फ़ील्ड वाला एक बड़ा ऑब्जेक्ट होता है जो पेलोड आकार पर हावी होता है। प्रतिक्रिया JSON है, इसलिए प्रत्येक मान एक स्ट्रिंग या संख्या है। अधिकांश फ़ील्ड छोटे हैं: उपयोगकर्ता ID, टाइमस्टैम्प, स्थिति कोड। एक फ़ील्ड में इमेजडेटा या फ़ाइल सामग्री शामिल है और यह एक 40-किलोबाइट Base64 स्ट्रिंग है। संपूर्ण प्रतिक्रिया 50 किलोबाइट है। वह एकल फ़ील्ड स्थानांतरण के 80 प्रतिशत के लिए जिम्मेदार है, जो बेकार लगता है क्योंकि सर्वर ने इसे मूल रूप से बाइट्स के रूप में भेजा था और क्लाइंट को अंततः बाइट्स की आवश्यकता होती है।

Base64 ने इस समस्या को हल किया: JSON में कोई मूल बाइट प्रकार नहीं है, इसलिए बाइनरी डेटा को एक स्ट्रिंग में लपेटा जाना चाहिए। Base64 मनमाने बाइट्स को ASCII वर्णों में परिवर्तित करता है जो JSON में सुरक्षित हैं। क्लाइंट और सर्वर दोनों को भेजने पर एनकोड करना होगा और प्राप्त होने पर डीकोड करना होगा, CPU ओवरहेड जोड़ना होगा। परिणामी पेलोड कच्चे बाइट्स से लगभग एक तिहाई बड़ा है। यह पोस्ट बताती है कि वह कन्वेंशन क्यों मौजूद है, व्यवहार में इसकी लागत क्या है, और एक अलग बाइनरी एंडपॉइंट के साथ JSON बाधा को तोड़ना इसके लायक है।

JSON कच्चे बाइट्स क्यों नहीं ले जा सकता - स्ट्रिंग्स वैध यूनिकोड टेक्स्ट होनी चाहिए, इसलिए मनमाने बाइट्स को टेक्स्ट रैपर की आवश्यकता होती है

JSON एक टेक्स्ट प्रारूप है जहां सभी मान मान्य यूनिकोड टेक्स्ट होने चाहिए। विनिर्देश स्ट्रिंग, संख्या, बूलियन और शून्य को परिभाषित करता है। इसमें बाइट सरणी या बफ़र प्रकार नहीं है। यदि API को छवि, क्रिप्टोग्राफ़िक हस्ताक्षर या फ़ाइल अपलोड जैसे बाइनरी डेटा वापस करने की आवश्यकता है, तो यह कच्चे बाइट्स को सीधे JSON ऑब्जेक्ट में नहीं डाल सकता है। बाइट्स में ऐसे अक्षर हो सकते हैं जिन्हें JSON पार्सर्स संरचनात्मक मार्कर के रूप में व्याख्या करते हैं। बाइनरी ब्लॉब के बीच में एक शून्य बाइट एक स्ट्रिंग को जल्दी समाप्त कर सकता है या पार्सर को तोड़ सकता है।

सामान्य समाधान बाइनरी डेटा को Base64 के रूप में एन्कोड करना है, जिससे ASCII वर्णों की एक स्ट्रिंग तैयार होती है जिसे JSON पार्सर्स सादे पाठ के रूप में मानते हैं। प्राप्तकर्ता क्लाइंट Base64 को वापस बाइट्स में डिकोड करता है और उनका उपयोग करता है। यह एन्कोडिंग चरण API स्तर पर होता है, जो अधिकांश डेवलपर्स से छिपा हुआ है, लेकिन यह एक वास्तविक लागत है जो तब जमा होती है जब APआई कई बाइनरी फ़ील्ड लौटाते हैं। अनुरोध-प्रतिक्रिया चक्र के दौरान JSON यौगिक में Base64 की लागत। आकार दंड पहला है: एन्कोडिंग ओवरहेड के कारण Base64 आउटपुट अपने इनपुट से लगभग 33 प्रतिशत बड़ा है।

लागत: एक तिहाई अधिक बाइट्स, डिकोड समय और मेमोरी प्रतियां - जहां प्रत्येक लागत एक विशिष्ट ग्राहक में दिखाई देती है

Base64-एनकोडेड होने पर 30-मेगाबाइट वीडियो फ़ाइल 40 मेगाबाइट बन जाती है। 30 मेगाबाइट के बजाय 40 डाउनलोड करने से मोबाइल टूलों पर बैंडविड्थ और बैटरी खर्च होती है, और धीमे कनेक्शन वाले उपयोगकर्ताओं के लिए समय खर्च होता है। दूसरी लागत CPU समय है। सर्वर को बाइनरी डेटा को JSON में स्ट्रिंग करने से पहले Base64 के रूप में एन्कोड करना होगा। क्लाइंट को JSON को पार्स करना होगा और फिर प्रत्येक Base64 फ़ील्ड को बाइट्स में डीकोड करना होगा। एकाधिक बाइनरी फ़ील्ड वाली प्रतिक्रिया या हजारों प्रतिक्रियाओं को संसाधित करने वाले क्लाइंट के लिए, वह CPU समय जमा होता है।

फोन जैसे प्रतिबंधित टूलों पर, JavaScript स्ट्रिंग ऑपरेशन और Base64 डिकोडिंग के लिए उपयोग किया जाने वाला टेक्स्ट डिकोडर बैटरी की खपत करता है और एप्लिकेशन को धीमा कर देता है। तीसरी लागत मेमोरी है: JSON पार्सर Base64 फ़ील्ड के लिए एक स्ट्रिंग ऑब्जेक्ट बनाता है, फिर डिकोडिंग Uint8Array के रूप में एक और प्रतिलिपि बनाता है। एप्लिकेशन द्वारा उपयोग किए जाने से पहले एक बड़े फ़ील्ड को मेमोरी में दो बार इंस्टेंट किया जाता है। एक कार्यशील उदाहरण लागत को स्पष्ट करता है। मान लीजिए कि एक API एंडपॉइंट एक 100-किलोबाइट अवतार छवि सहित उपयोगकर्ता प्रोफ़ाइल डेटा लौटाता है। सर्वर डिस्क से छवि को बाइट्स के रूप में पढ़ता है, इसे Base64 में एन्कोड करता है, और इसे JSON प्रतिक्रिया में शामिल करता है।

व्यावहारिक उदाहरण: API प्रतिक्रिया से Base64 फ़ील्ड का निरीक्षण करना - सर्वर ने वास्तव में क्या भेजा है इसकी पुष्टि करने के लिए इसे ब्राउज़र में डिकोड करना

JSON प्रतिक्रिया अब लगभग 135 किलोबाइट (33% overhead प्लस अन्य फ़ील्ड) है। क्लाइंट 100 के बजाय 135 किलोबाइट डाउनलोड करता है। ब्राउज़र में, JSON पार्सर Base64 डेटा के लिए JavaScript स्ट्रिंग ऑब्जेक्ट बनाता है।

जब एप्लिकेशन को छवि की आवश्यकता होती है, तो यह Base64 डिकोडर को कॉल करता है, जो मूल 100 किलोबाइट का Uint8Array बनाता है। डिकोडिंग के कुछ मिलीसेकंड के लिए, दोनों ऑब्जेक्ट मेमोरी में मौजूद रहते हैं। यदि पेज अवतारों के साथ दस प्रोफ़ाइल प्रदर्शित करता है, तो लागत कई गुना बढ़ जाती है। API के लिए विकल्प यह है कि वह प्रत्येक अवतार संसाधन के लिए एक अलग URL के साथ JSON प्रतिक्रिया लौटाए, जिससे ब्राउज़र अपने मूल कैशिंग, प्रगतिशील रेंडरिंग और मेमोरी प्रबंधन के साथ छवि डाउनलोड को संभाल सके।

विकल्प: मल्टीपार्ट, अलग-अलग डाउनलोड URL और कच्चे बाइनरी एंडपॉइंट - प्रत्येक का ट्रेड-ऑफ

JSON में बाइनरी को शामिल करने और इसे अलग से लाने के बीच का समझौता API उद्देश्य और उपयोग पैटर्न पर निर्भर करता है। एक खोज परिणाम पेज के लिए जो सैकड़ों छोटी थंबनेल छवियां लौटाता है, प्रत्येक को एक अलग अनुरोध के रूप में लाने से HTTP कनेक्शन पूलिंग और कैशिंग समाप्त हो जाती है। JSON प्रतिक्रिया में उन्हें Base64 के रूप में इनलाइन करना तेज़ हो सकता है। एक विस्तृत प्रोफ़ाइल पेज के लिए जो एक या दो उच्च-रिज़ॉल्यूशन छवियों का अनुरोध करता है, अलग-अलग डाउनलोड स्पष्ट रूप से बेहतर हैं। API दस्तावेज़ में Base64 फ़ील्ड का अधिकतम आकार और ग्राहकों को अलग-अलग समापन बिंदुओं की अपेक्षा कब करनी चाहिए, यह बताना चाहिए।

यदि कोई फ़ील्ड नियमित रूप से एक या दो किलोबाइट से अधिक हो जाती है, तो इनलाइन-Base64 रणनीति एक संकेत है कि API डिज़ाइन पर पुनर्विचार की आवश्यकता है। JSON में Base64 के विकल्प मौजूद हैं लेकिन प्रत्येक में समझौता है। मल्टीपार्ट MIME प्रतिक्रियाएँ बाइनरी और टेक्स्ट को अलग करती हैं इसलिए बाइनरी अनुभाग को कच्चे बाइट्स के रूप में भेजा जाता है और केवल टेक्स्ट अनुभाग JSON होता है। इसके लिए क्लाइंट को जटिलता जोड़ते हुए केवल JSON.parse को कॉल करने के बजाय एक मल्टीपार्ट संदेश को पार्स करने की आवश्यकता होती है। JSON प्रतिक्रिया में एक अलग डाउनलोड URL क्लाइंट को बाइनरी संसाधन अलग से लाने के लिए इंगित करता है।

आपके API दस्तावेज़ों में बताए जाने लायक परंपराएँ - मानक बनाम Base64url वर्णमाला, पैडिंग और अधिकतम आकार

यह तब अच्छी तरह से काम करता है जब बाइनरी संसाधन बड़ा होता है या मेटाडेटा की तुलना में कम बार एक्सेस किया जाता है। एक कच्चा बाइनरी एंडपॉइंट जो केवल बाइट्स लौटाता है और JSON को पूरी तरह से छोड़ देता है, सबसे सरल तरीका है लेकिन JSON द्वारा प्रदान की जाने वाली संरचना को हटा देता है। कुछ APआई संपीड़ित बाइनरी डेटा लौटाते हैं और Base64-एनकोड करते हैं, जो आकार के दंड को कम करते हैं लेकिन डीकंप्रेसन ओवरहेड जोड़ते हैं। चुनाव अपेक्षित उपयोग पर निर्भर करता है: छोटे फ़ील्ड ठीक इनलाइन होते हैं, बड़े फ़ील्ड अलग-अलग संसाधनों में होते हैं, और संरचित डेटा Base64 लागत के साथ भी JSON में रखने लायक है।

अंतरसंचालनीयता के लिए कन्वेंशन मायने रखते हैं। APआई जो Base64-एनकोड बाइनरी डेटा को स्पष्ट रूप से दस्तावेजित करना चाहिए और बताना चाहिए कि वर्णमाला मानक है या URL-सुरक्षित है। मानक Base64 + और /, का उपयोग करता है जो JSON स्ट्रिंग्स में सुरक्षित हैं लेकिन URL में नहीं। URL-सुरक्षित Base64 उन्हें - और _ से प्रतिस्थापित करता है, जो डेटा के लिए उपयुक्त है: URI लेकिन अनावश्यक रूप से JSON में बच जाता है। दस्तावेज़ में निर्दिष्ट होना चाहिए कि क्या पैडिंग शामिल है या छोड़ी गई है, क्योंकि दोनों वैध Base64 हैं लेकिन एक क्लाइंट जो पैडिंग की अपेक्षा करता है और अनपैडेड डेटा प्राप्त करता है वह चुपचाप विफल हो जाएगा या कचरा उत्पन्न करेगा।

इसमें क्या शामिल नहीं है - प्रोटोबफ़, CBOR और अन्य बाइनरी क्रमबद्धता प्रारूप

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

छवियों जैसे बाइनरी डेटा के लिए, हेक्स व्यू आपको बाइट्स दिखाता है। इससे यह पुष्टि करने में मदद मिलती है कि सर्वर ने वही भेजा है जिसकी आपको अपेक्षा थी और आपका क्लाइंट डिकोडर सही ढंग से काम कर रहा है। यदि कोई फ़ील्ड अप्रत्याशित डेटा को डिकोड करता है, तो समस्या सर्वर एन्कोडिंग में है या आप फ़ील्ड को कैसे कॉपी कर रहे हैं। यदि यह आंशिक ब्लॉब में डिकोड होता है, तो फ़ील्ड को छोटा कर दिया गया हो सकता है या Base64 लंबाई गलत हो सकती है। किसी फ़ाइल में फ़ील्ड लिखने और बाहरी टूल खोलने की तुलना में स्थानीय डिकोडिंग डिबगिंग को गति देती है।

टेकवे: JSON में Base64 एक समझौता है, इसलिए इसे दस्तावेजित करें - कैसे Base64 एनकोडर और डिकोडर आपको स्थानीय रूप से एन्कोडेड फ़ील्ड का निरीक्षण और सत्यापन करने में मदद करता है

APआई में Base64 के लिए व्यावहारिक दृष्टिकोण परहेज के बजाय जागरूकता है। Base64 JSON में बाइनरी डेटा ले जाने का मानक तरीका है और यह काम करता है। समझें कि प्रत्येक Base64 फ़ील्ड का आकार एक तिहाई अधिक होता है और प्रति अनुरोध-प्रतिक्रिया चक्र में कुछ मिलीसेकंड CPU समय लगता है। प्रमाणीकरण टोकन जैसे छोटे महत्वपूर्ण मेटाडेटा के लिए (जहां JWT स्वयं Base64-एन्कोडेड है), लागत नगण्य है। बड़े अनुलग्नकों के लिए, प्रश्न करें कि क्या बाइनरी को एक ही प्रतिक्रिया में या एक अलग संसाधन के रूप में यात्रा करनी चाहिए।

अपने API विनिर्देश में एन्कोडिंग योजना और अधिकतम आकार का दस्तावेज़ीकरण करें। प्रतिक्रियाओं का निरीक्षण करते समय, फ़ील्ड डिकोड को सही ढंग से सत्यापित करने और सर्वर ने वास्तव में क्या भेजा है यह समझने के लिए Base64 एनकोडर और डिकोडर का उपयोग करें। वह अनुशासन व्यापार-बंद को दृश्यमान रखता है और निर्णय आकस्मिक होने के बजाय जानबूझकर किया जाता है।