Base64 encode करें

कुछ लिखिए या चिपकाइए और टाइप करते-करते उसका Base64 सामने आ जाएगा। Base64 इसलिए बना है कि बाइट ऐसे रास्तों से निकल सकें जो अक्षरों का बहुत छोटा दायरा ही मानते हैं — यही वजह है कि यह data URI में, ईमेल के अनुलग्नकों में और Authorization हेडर में मिलता है, और वहाँ नहीं मिलता जहाँ कोई इंसान उसे पढ़ने वाला हो। आपका लिखा हुआ अपलोड नहीं होता: encoding इसी पन्ने पर होती है।

URL-सुरक्षित वाली + और / की जगह - और _ रखती है, जिन्हें query string बिना escape किए मान लेता है।

नतीजा

आप लिखते जाइए, जवाब यहाँ आता जाएगा।

  • कहाँ चलता है

    कुछ भी अपलोड नहीं होता, क्योंकि कोई फ़ाइल है ही नहीं — गणना इसी पन्ने में होती है।

  • न कतार, न खाता

    यह उतनी ही तेज़ी से जवाब देता है जितनी आपकी मशीन देती है, और कभी नहीं पूछता कि आप कौन हैं।

  • जितनी बार चाहें

    न कुछ गिना जाता है, न कोई सीमा है — दोबारा जवाब देने में हमारा कुछ ख़र्च नहीं होता।

काम कैसे करता है

  1. टेक्स्ट खाने में चिपकाइए।
  2. वर्णमाला चुनिए: मानक वाली, या URL-सुरक्षित वाली अगर मान किसी पते के भीतर जाना है।
  3. नतीजा कॉपी कर लीजिए। वह डिवाइस से बाहर नहीं गया है।

Base64 असल में करता क्या है

Base64 न एन्क्रिप्ट करता है न सिकोड़ता है: वह बाइट को सिर्फ़ 64 ऐसे अक्षरों से दोबारा लिखता है जो लगभग किसी भी रास्ते से बचकर निकल आते हैं। वह तीन बाइट लेता है, उन्हें 24 बिट की तरह देखता है और छह-छह बिट के चार टुकड़ों में बाँट देता है, और हर टुकड़ा तालिका के एक अक्षर में बदल जाता है।

इसी से उसकी क़ीमत निकलती है: नतीजा हमेशा मूल से एक-तिहाई बड़ा होता है। यह उस रास्ते से निकलने का दाम है जो सिर्फ़ टेक्स्ट समझता है, और यही वजह है कि ईमेल का अनुलग्नक भीतर की फ़ाइल से भारी होता है — ईमेल भीतर से आज भी टेक्स्ट का प्रोटोकॉल है।

दो वर्णमालाएँ, और दूसरी की ज़रूरत कब पड़ती है

मानक वर्णमाला आख़िरी दो अक्षरों के लिए `+` और `/` इस्तेमाल करती है। इन दोनों का URL के भीतर अपना मतलब है: तिरछी लकीर path के हिस्से अलग करती है और plus को query string में स्पेस पढ़ा जाता है। इसलिए मानक Base64 का मान जब किसी पते में डाला जाता है तो पहुँचता है, पर बदला हुआ पहुँचता है।

URL-सुरक्षित रूप इन दोनों की जगह `-` और `_` रखता है, जिनका पते के किसी हिस्से में कोई मतलब नहीं होता। JWT यही इस्तेमाल करते हैं, और इसीलिए हेडर से कॉपी किए हुए token में न तिरछी लकीरें होती हैं न plus। अगर मान को किसी पते में सफ़र करना है तो यही विकल्प है; वरना बाक़ी सब मानक वाली की उम्मीद करते हैं।

आख़िर में लगने वाला बराबर का चिह्न

Base64 तीन-तीन बाइट लेकर चलता है। जब इनपुट तीन का गुणक नहीं होता तो एक या दो बाइट बच जाती हैं, और उस भराव को आख़िर में एक या दो बराबर के चिह्नों से दर्ज किया जाता है। इसीलिए नतीजा `=` पर, `==` पर या किसी चिह्न के बिना ख़त्म होता है, और इसीलिए उसकी लंबाई हमेशा चार का गुणक होती है।

यह भराव कुछ विनिर्देशों में वैकल्पिक है और कुछ में अनिवार्य, जिससे एक बार-बार होने वाली नोकझोंक पैदा होती है: JWT उसे जान-बूझकर छोड़ देते हैं, जबकि बहुत सी लाइब्रेरियाँ उसके बिना decode करने से मना कर देती हैं। अगर कोई चीज़ ऐसे मान को मना कर रही है जो देखने में ठीक है, तो सबसे पहले अक्षरों की गिनती देखिए।

देवनागरी का हर अक्षर तीन बाइट का है

Base64 बाइट को encode करता है, अक्षरों को नहीं, इसलिए पहले यह तय करना पड़ता है कि टेक्स्ट बाइट में कैसे बदलेगा। यहाँ हमेशा UTF-8 है, जहाँ देवनागरी का हर अक्षर और हर मात्रा तीन बाइट लेती है — क्योंकि पूरा देवनागरी खंड U+0900 से U+097F के बीच बैठा है और वह दायरा UTF-8 में तीन बाइट में लिखा जाता है।

नतीजा गिनने लायक़ है: «नमस्ते» छह code point हैं, यानी 18 बाइट, यानी Base64 में 24 अक्षर — जबकि उतने ही अंग्रेज़ी अक्षरों के लिए 8 बनते। जब कोई फ़ील्ड बाइट में सीमित हो और सीमा अक्षर गिनकर तय की गई हो, तो हिंदी सामग्री उस सीमा को तीन गुना तेज़ी से लाँघती है, और यही वह जगह है जहाँ यह पन्ना गिनती का काम भी कर देता है।

Basic Auth सुरक्षा नहीं है

`Authorization: Basic` हेडर ठीक-ठीक `उपयोक्ता:पासवर्ड` का Base64 है, और इससे ज़्यादा कुछ नहीं। जो भी हेडर देख ले वह उसे एक पल में उलट सकता है, क्योंकि वहाँ कोई कुंजी है ही नहीं: यह encoding है, encryption नहीं।

उन क्रेडेंशियल की रक्षा HTTPS करता है और सिर्फ़ HTTPS करता है। इसीलिए सादे HTTP पर Basic Auth पासवर्ड को खुला भेजने के बराबर है, और इसीलिए किसी स्क्रीनशॉट में, किसी टिकट में या किसी लॉग में पड़ा ऐसा हेडर एक उघड़ी हुई क्रेडेंशियल है। उसका पढ़ा न जा सकना कुछ नहीं बदलता।

Data URI और उसकी व्यावहारिक सीमा

`src` के भीतर Base64 में रखी तस्वीर एक रिक्वेस्ट बचाती है, और किसी छोटे आइकन या कुछ किलोबाइट के SVG के लिए यह समझदारी है। उसके आगे हिसाब उलट जाता है: फ़ाइल एक-तिहाई बढ़ जाती है, HTML के भीतर धँस जाती है और इसलिए अलग से कैश नहीं होती, और ब्राउज़र को कुछ भी बनाने से पहले उसे पढ़ना पड़ता है।

जहाँ पलड़ा बदलता है वह बिंदु पन्ने पर निर्भर है, पर मोटा नियम टिकता है: कुछ किलोबाइट से नीचे data URI लगभग हमेशा जीतती है; कुछ दसियों किलोबाइट से ऊपर लगभग हमेशा हारती है। भीतर धँसी बड़ी तस्वीर हर मुलाक़ात को फूले हुए HTML के पूरे डाउनलोड में बदल देती है।

यह कुछ छिपाने का तरीक़ा क्यों नहीं है

यह अक्सर किसी ऐप के कोड में, किसी कॉन्फ़िग फ़ाइल में या किसी स्क्रिप्ट में कोई कुंजी «छिपाने» के तरीक़े की तरह सामने आता है। यह कुछ नहीं छिपाता: वापसी एक बटन भर है, और लीक हुए रहस्य ढूँढ़ने वाले औज़ार Base64 स्ट्रिंग को ठीक इसलिए पहचान लेते हैं कि उसका ढाँचा बहुत आसानी से पकड़ में आता है।

यह इतना ज़रूर करता है कि ऊपर-ऊपर देखने वाले को चेतावनी नहीं मिलती, और असली दिक़्क़त यही है: खुला पड़ा रहस्य दिख जाता है और सुधर जाता है, Base64 वाला समीक्षा पार कर जाता है। अगर सचमुच कुछ छिपाना है तो ऐसी encryption चाहिए जिसकी कुंजी कहीं और रहती हो, या फिर उस चीज़ को वहाँ रखना ही नहीं चाहिए।

वे पंक्ति-विच्छेद जो बच जाते हैं

ईमेल Base64 को 76 अक्षरों की पंक्तियों में तोड़ता है क्योंकि 1996 का एक मानक ऐसा कहता है, और PEM रूप वाले प्रमाणपत्र 64 अक्षरों की पंक्तियाँ इस्तेमाल करते हैं। यह रूप पूरी तरह वैध है, पर बहुत से आजकल के decoder पंक्ति-विच्छेदों पर अटक जाते हैं अगर उन्हें पहले हटाया न जाए।

यह पन्ना एक अटूट पंक्ति बनाता है, जिसकी उम्मीद व्यावहारिक रूप से आज का हर API करता है। अगर नतीजे को कहीं ऐसी जगह चिपकाना है जो पंक्तियों वाला रूप माँगती है, तो तोड़ना आपको ख़ुद करना होगा — और अगर आप पंक्ति-विच्छेद वाली कोई चीज़ decode कर रहे हैं, तो इस साइट का decoder उन्हें अनदेखा कर देता है।

Encode करना किसी चीज़ की जाँच नहीं करता

कोई भी टेक्स्ट Base64 में बदल जाता है: यहाँ अवैध इनपुट जैसा कुछ है ही नहीं, और इसलिए इस दिशा में कोई त्रुटि भी संभव नहीं। यह सुविधाजनक है और इसमें एक जाल छिपा है, क्योंकि Base64 की कोई स्ट्रिंग भीतर पूरी तरह कचरा रखते हुए भी बेदाग़ दिख सकती है।

जाँच, अगर चाहिए, तो पहले होनी चाहिए: JSON encode कर रहे हैं तो पहले उसे validate कर लीजिए; कोई पहचान-संख्या encode कर रहे हैं तो देख लीजिए कि वही है। ख़राब मान encode होने के बाद ठीक मान जैसा ही दिखता है, और ग़लती दूसरे छोर पर सामने आती है, जहाँ उसे ढूँढ़ना कहीं ज़्यादा महँगा है।

DPDP Act के लिहाज़ से इसका क्या मतलब है

इस खाने में जो चिपकाया जाता है वह अक्सर ठीक वही होता है जिसे हिलाना नहीं चाहिए: क्रेडेंशियल, ग्राहकों के डेटा वाला कोई payload, किसी कॉन्फ़िग फ़ाइल की सामग्री। चूँकि encoding पन्ने पर ही होती है, वह सामग्री हम तक पहुँचती ही नहीं और इसलिए उस पर हमारी कोई प्रोसेसिंग की भूमिका बनती ही नहीं।

यह नेटवर्क पैनल में जाँचा जा सकता है: औज़ार चलाते हुए ऐसी कोई रिक्वेस्ट नहीं निकलती जो आपका इनपुट ले जाए। जो होता है वह निजता पन्ने पर लिखा है — आपका आना, और विज्ञापन तथा आँकड़ों की रिक्वेस्ट। खाने की सामग्री उनमें नहीं है, और इस क़िस्म के मान के साथ यही एकमात्र बात मायने रखती है।

यह पन्ना decode भी क्यों नहीं करता

Decode करने का अपना पन्ना है, और यह अलगाव सुविधा के लिए नहीं है। जो encode कर रहा है वह कुछ बना रहा है और उसके सामने एक फ़ैसला है: कौन-सी वर्णमाला। जो decode कर रहा है वह कुछ पढ़ रहा है जो उस तक पहुँचा है, और उसकी समस्या दूसरी है: जब बाहर आने वाली चीज़ टेक्स्ट न हो तो क्या करें।

दोनों पन्ने एक ही इंजन साझा करते हैं और अलग-अलग बातें समझाते हैं, क्योंकि उनकी ग़लतियाँ अलग हैं। उन्हें जोड़ देना हर आने वाले को वह आधा हिस्सा पढ़वाता जो उसके काम का नहीं, और ठीक वे ब्योरे पीछे छूट जाते जिनके लिए वह आया था।

Base64 encode करें: आम सवाल

क्या Base64 मेरे टेक्स्ट को एन्क्रिप्ट करता है?

नहीं। यह encoding है, encryption नहीं: कोई कुंजी नहीं है और कोई भी इसे एक पल में उलट सकता है। यह बाइट को उन रास्तों से ले जाने के लिए है जो सिर्फ़ टेक्स्ट मानते हैं, कुछ छिपाने के लिए नहीं।

URL-सुरक्षित वर्णमाला की ज़रूरत कब पड़ती है?

जब मान किसी पते के भीतर जा रहा हो। मानक वर्णमाला + और / इस्तेमाल करती है, और दोनों का URL में अपना मतलब है; सुरक्षित रूप उनकी जगह - और _ रखता है। JWT यही इस्तेमाल करते हैं।

नतीजा एक या दो बराबर के चिह्नों पर क्यों ख़त्म होता है?

वह भराव है। Base64 तीन-तीन बाइट लेकर चलता है, और जब इनपुट तीन का गुणक न हो तो बची जगह एक या दो = से दर्ज होती है। इसीलिए लंबाई हमेशा चार का गुणक रहती है।

मेरा नतीजा किसी दूसरे औज़ार से क्यों नहीं मिलता?

लगभग हमेशा इसलिए कि टेक्स्ट किसी और तरीक़े से बाइट में बदला गया था। यहाँ हमेशा UTF-8 है, जहाँ देवनागरी का हर अक्षर तीन बाइट है। अगर दूसरी तरफ़ Kruti Dev जैसी फ़ॉन्ट-आधारित सामग्री थी तो वहाँ बाइट असल में ASCII थीं।

क्या मेरा लिखा हुआ अपलोड होता है?

नहीं। Encoding इसी पन्ने पर, आपके ब्राउज़र में होती है। लिखते हुए नेटवर्क पैनल खोल लीजिए: ऐसी कोई रिक्वेस्ट नहीं निकलती जो आपका इनपुट ले जाए।

और टूल्स