डेवलपर टूल · Base64 एनकोडर और डिकोडर
btoa() इमोजी क्यों डालता है और JavaScript में Base64-एन्कोड UTF-8 कैसे करें
· यह काम किस प्रकार करता है
Base64 यूनिकोड एन्कोडिंग
btoa() केवल U+00FF तक के वर्णों को स्वीकार करता है, इसलिए उच्चारण पाठ, CJK और इमोजी फेंकता है। यह पोस्ट दिखाती है कि फ़ंक्शन वास्तव में क्या अपेक्षा करता है और TextEncoder आपको एक सही UTF-8 Base64 स्ट्रिंग कैसे प्राप्त करता है।
क्यों btoa यूनिकोड पर फेंक सकता है - और चुपचाप एक उच्चारण को गलत तरीके से लिख सकता है
btoa('😀') को कॉल करने से InvalidCharacterError आ जाता है क्योंकि इमोजी एक बाइट-आकार की कोड इकाई में फिट नहीं हो सकता है। एक सूक्ष्मतर त्रुटि btoa("é") है: पूर्वनिर्मित é U+00E9 है, 256 के नीचे, इसलिए btoa इसे स्वीकार करता है लेकिन लैटिन-1 byte E9 को एन्कोड करता है, UTF-8 बाइट्स C3 A9 को नहीं। समान दृश्य उच्चारण को ई के साथ-साथ एक संयोजन चिह्न के रूप में लिखा जा सकता है क्योंकि चिह्न स्वीकृत सीमा से बाहर है। कार्यपुस्तिका के आशुलिपि "एक उच्चारण फेंकता है" के लिए इस योग्यता की आवश्यकता होती है: एक स्ट्रिंग जोर से विफल हो सकती है या चुपचाप गलत बाइट्स उत्पन्न कर सकती है।
btoa() वास्तव में क्या एन्कोड करता है: कोड इकाइयों की एक बाइनरी स्ट्रिंग 0–255 - फ़ंक्शन को यूनिकोड टेक्स्ट के बजाय लैटिन-1 bytes के आसपास क्यों डिज़ाइन किया गया था
btoa एक "बाइनरी स्ट्रिंग" का उपभोग करता है: प्रत्येक JavaScript वर्ण कोड इकाई 0–255 की सीमा में होनी चाहिए और एक बाइट के लिए होती है। यह यूनिकोड टेक्स्ट एन्कोडिंग, भाषा या सामान्यीकरण को नहीं समझता है। एक सूक्ष्म इमोजी को दो UTF-16 सरोगेट कोड इकाइयों द्वारा दर्शाया जाता है, दोनों 255 से बहुत बड़े हैं, इसलिए कच्चे JavaScript स्ट्रिंग को सीधे भेजना काम नहीं कर सकता है। आउटपुट को बाइट्स की एन्कोडिंग के रूप में मानें, अमूर्त वर्णों की नहीं।
UTF-8 पहला, Base64 दूसरा - किसी भी Base64 वर्णमाला के लागू होने से पहले टेक्स्ट को बाइट्स क्यों बनना चाहिए
TextEncoder पहले JavaScript स्ट्रिंग को उसके UTF-8 बाइट अनुक्रम में बदल देता है। फिर प्रत्येक बाइट को बाइनरी-स्ट्रिंग कैरेक्टर में बदलें और उस बाइनरी स्ट्रिंग को btoa में पास करें, या किसी अन्य API का उपयोग करें जो सीधे बाइट्स स्वीकार करता है। डिकोडिंग के लिए, एटोब बाइनरी स्ट्रिंग लौटाता है; इसके बाइट मान पुनर्प्राप्त करें और उन्हें TextDecoder("utf-8") को दें। ToolAcre एक सख्त डिकोडर का उपयोग करता है जो प्रतिस्थापन वर्णों को चुपचाप सम्मिलित करने के बजाय विकृत UTF-8 को अस्वीकार कर देता है।
कार्यान्वित उदाहरण: TextEncoder और btoa के साथ 'कैफ़े 😀' एन्कोडिंग - बाइट अनुक्रम, मध्यवर्ती बाइनरी स्ट्रिंग और अंतिम आउटपुट
शाब्दिक टेक्स्ट कैफे 😀 के लिए, UTF-8 बाइट्स हेक्साडेसिमल में 63 61 66 C3 A9 20 F0 9F 98 80 हैं: ASCII सी-ए-एफ, ई के लिए दो बाइट्स, एक स्पेस और इमोजी के लिए चार बाइट्स। इन दस बाइट्स का Base64 Y2Fmw6kg8J+YgA== है। पैडिंग और वर्णमाला केवल बाइट्स का वर्णन करते हैं; वे भाषा पर लेबल नहीं लगाते. ToolAcre के UTF-8 मोड के साथ प्रत्यक्ष btoa ("कैफ़े 😀") विफलता की तुलना करें, फिर उसके परिणाम को डीकोड करें और उसी दृश्य उच्चारण को सत्यापित करें और इमोजी जीवित रहें।
पुरानी unescape(encodeURIComponent()) ट्रिक और यह एक हैक क्यों है - यह हुड के नीचे क्या करता है और इसे हतोत्साहित क्यों किया जाता है
एक ऐतिहासिक समाधान btoa(unescape(encodeURIComponent(text))) है। encodeURIComponent प्रतिशत-एनकोड UTF-8 और unescape प्रतिशत ट्रिपल को एकल कोड इकाइयों के रूप में पुन: पैक करता है, लेकिन unescape को अस्वीकृत कर दिया गया है, पढ़ने में कठिन है और विकृत अकेले सरोगेट्स के आसपास अजीब है। यह रूपांतरण को URL प्रोसेसिंग जैसा बनाता है, भले ही कोई URL मौजूद न हो। TextEncoder इच्छित सीमा को स्पष्ट रूप से बताता है: टेक्स्ट एक बार बाइट्स बन जाता है, और Base64 उसके बाद ही संचालित होता है।
दूसरी तरफ डिकोडिंग - एटोब को टेक्स्टडिकोडर के साथ जोड़ना ताकि राउंड ट्रिप दोषरहित हो
एटोब के बाद, मनमाने ढंग से बाइनरी बाइट्स पर decodeURIComponent को कॉल न करें और आशा करें कि वे टेक्स्ट बन जाएंगे। कैरेक्टर कोड को Uint8Array में बदलें और इसे TextDecoder के माध्यम से पास करें। कैफे 😀 उदाहरण में परिणाम मूल दस-बाइट UTF-8 अनुक्रम है, फिर मूल स्ट्रिंग है। यदि Base64 छवि या संपीड़ित-फ़ाइल बाइट्स को डीकोड करता है, तो यह बिल्कुल भी वैध UTF-8 टेक्स्ट का प्रतिनिधित्व नहीं कर सकता है; ToolAcre रिपोर्ट करता है कि बाइनरी डेटा दिखावा करने के बजाय पढ़ने योग्य गद्य है।
इसमें क्या शामिल नहीं है - फ़ाइल और बाइनरी-ब्लॉब एन्कोडिंग, Base64url वेरिएंट और बड़े इनपुट स्ट्रीमिंग
यह स्पष्टीकरण UTF-8 के रूप में एन्कोड किए गए पाठ से संबंधित है। फ़ाइल और ब्लॉब Base64, JWT सेगमेंट के लिए Base64url और मल्टी-गीगाबाइट डेटा की वृद्धिशील एन्कोडिंग में अलग-अलग इंटरफ़ेस या मेमोरी आवश्यकताएं होती हैं। Base64 भी किसी टोकन को एन्क्रिप्ट नहीं करता है: इसे रखने वाला कोई भी व्यक्ति बाइट्स को डीकोड कर सकता है। डिकोडर सामान्य लापता पैडिंग और व्हाइटस्पेस को स्वीकार कर सकता है, लेकिन इंटरऑपरेबिलिटी अभी भी यह जानने पर निर्भर करती है कि पेलोड टेक्स्ट है या मनमाना बाइनरी डेटा है।
टेकअवे: बाइट्स को एनकोड करें, स्ट्रिंग्स को नहीं, और राउंड ट्रिप की जांच करें - Base64 एनकोडर और डिकोडर आपके लिए UTF-8 चरण कैसे करता है ताकि एक्सेंट, CJK और इमोजी जीवित रहें
बाइट्स को एन्कोड करें, कच्ची JavaScript स्ट्रिंग्स को नहीं, फिर राउंड ट्रिप की जाँच करें। Base64 एनकोडर और डिकोडर ब्राउज़र में पेस्ट किए गए टेक्स्ट को रखते हुए आपके लिए टेक्स्टएनकोडर और टेक्स्टडिकोडर चरण निष्पादित करता है। RFC 4648 वर्णमाला और पैडिंग निर्दिष्ट करता है; UTF-8 अलग कैरेक्टर-टू-बाइट अनुबंध की आपूर्ति करता है। उन दो परतों को मिलाना InvalidCharacterError और शांत लैटिन-1 भ्रष्टाचार दोनों की जड़ है।