डेवलपर के औज़ार

वे छोटे-छोटे काम जो एक पूरी दोपहर तोड़ देते हैं: कोई JWT जिसे पढ़ना है, कोई payload जिसे पढ़ने लायक़ बनाना है, कोई स्ट्रिंग जिसे किसी query के भीतर ज़िंदा बचकर निकलना है। यहाँ का हर औज़ार उसी पन्ने पर गणना करता है जिस पर आप खड़े हैं — और असल बात यही है, क्योंकि डेवलपर ऐसे खानों में जो चिपकाते हैं वह अक्सर ठीक वही होता है जिसे उनके डिवाइस से बाहर जाना ही नहीं चाहिए था।

19 औज़ार

  • JSON format करेंकिसी के पास एक ही पंक्ति में फैली JSON की दीवार आ गई है — कोई API जवाब, कोई लॉग फ़ील्ड, कोई कॉन्फ़िग — और आगे कुछ करने से पहले उसे ढाँचा देखना है।
  • Base64 decode करेंकिसी के सामने बेमतलब दिखती एक स्ट्रिंग है और उसे जानना है कि उसमें क्या लिखा है — कोई JWT, किसी Kubernetes secret का मान, लॉग की कोई पंक्ति — बिना उसे किसी अजनबी को सौंपे।
  • Unix timestamp बदलेंकिसी को किसी लॉग में, किसी डेटाबेस कॉलम में या किसी JSON payload में दस या तेरह अंकों का नंबर दिखा है और उसे जानना है कि वह कौन-सा क्षण है, और किस समय-क्षेत्र में।
  • JSON validate करेंकिसी की JSON को कोई चीज़ मना कर रही है और वजह नहीं बता रही, और उसे पहली अटकन की पंक्ति और कॉलम चाहिए।
  • Base64 encode करेंकिसी को कोई स्ट्रिंग वहाँ डालनी है जहाँ वह जैसी है वैसी क़बूल नहीं होती: कोई data URI, कोई Basic Auth हेडर, कोई JSON फ़ील्ड जिसे ऐसे रास्ते से बचकर निकलना है जिसकी अपनी राय है कि कौन-सी बाइट चलेंगी।
  • SHA-256 hash बनाएँकिसी को किसी टेक्स्ट का SHA-256 चाहिए — कोई integrity मान, मिलान के लिए कोई fingerprint, कोई तय पहचान — और वह चाहता है कि जवाब आज का हो और टूटा हुआ न हो।
  • URL encode करेंकोई हाथ से URL बना रहा है — कोई पैरामीटर जिसमें स्पेस या ampersand हैं, कोई redirect पता जिसे दूसरे पते के भीतर एक मान की तरह बचना है — और उसे जानना है कि किन अक्षरों को escape करना है और किन्हें नहीं।
  • UUID बनाएँकिसी को अभी एक या कई पहचान-संख्याएँ चाहिए — किसी टेस्ट डेटा के लिए, किसी माइग्रेशन के लिए, किसी कॉन्फ़िग फ़ाइल के लिए — और इसके लिए वह terminal नहीं खोलना चाहता।
  • MD5 hash बनाएँकिसी को किसी टेक्स्ट का MD5 चाहिए — डेटाबेस के किसी मान से मिलाने के लिए, कोई cache key दोबारा बनाने के लिए, या किसी पुराने इंटरफ़ेस के लिए जो अब भी यही माँगता है।
  • URL decode करेंकोई लॉग से, किसी analytics निर्यात से या किसी त्रुटि-संदेश से निकाला हुआ URL पढ़ रहा है, और काम की चीज़ percent sequences के नीचे दबी हुई है।
  • HTML encode करेंकोई अपने पन्ने पर ऐसा टेक्स्ट डाल रहा है जो उसने ख़ुद नहीं लिखा — कोई टिप्पणी, कोई उत्पाद-विवरण, markup का कोई नमूना — और उसे चाहिए कि जो अक्षर टैग बन जाते वे अक्षर ही बने रहें।
  • HTML decode करेंकिसी के सामने ऐसा टेक्स्ट है जहाँ अक्षरों की जगह उनके escape रूप पड़े हैं — किसी डेटाबेस फ़ील्ड से, किसी RSS feed से, किसी scraper के निर्यात से — और वह पढ़ना चाहता है कि असल में लिखा क्या है।
  • JSON minify करेंकोई सजी-सजाई JSON को एक ही पंक्ति में लाना चाहता है, क्योंकि उसे किसी कॉन्फ़िग वेरिएबल में, किसी डेटाबेस फ़ील्ड में या ऐसे रास्ते में समाना है जहाँ हर बाइट गिनी जाती है।
  • SHA-1 hash बनाएँकिसी को SHA-1 बनाना पड़ रहा है क्योंकि कोई और चीज़ यही माँग रही है — कोई Git ऑब्जेक्ट, कोई पुरानी हस्ताक्षर-योजना, 2017 से पहले का कोई इंटरफ़ेस — इसलिए नहीं कि उसने इसे चुना है।
  • URL तोड़ेंकिसी के सामने एक लंबा पता है और उसे उसके हिस्से अलग-अलग देखने हैं — host, port, path, query, fragment — बजाय इसके कि वह मन में गिनता रहे।
  • Hex encode करेंकिसी को किसी टेक्स्ट के पीछे की बाइट देखनी हैं — किसी प्रोटोकॉल के लिए, किसी dump से मिलान के लिए, ऐसे फ़ील्ड के लिए जो hexadecimal माँगता है — और उन्हीं विभाजकों के साथ जो उसका औज़ार पढ़ता है।
  • Hex decode करेंकिसी के पास किसी लॉग, किसी नेटवर्क कैप्चर या किसी त्रुटि-संदेश से आया hex dump है और वह जानना चाहता है कि उसके पीछे कौन-सा टेक्स्ट है।
  • Query string तोड़ेंकिसी के पास ट्रैकिंग पैरामीटरों से भरा query string है और उसे हर पैरामीटर की अपनी पंक्ति चाहिए, मान decode किए हुए और दोहराई गई कुंजियाँ ग़ायब हुए बिना।
  • UUID जाँचेंकिसी के सामने एक पहचान-संख्या है और उसे जानना है कि वह सही बनी हुई UUID है या नहीं, और वह कौन-सा version और कौन-सा variant बताती है।

यहाँ «लोकल में चलता है» पसंद का मामला नहीं है

लोग Base64 decoder में जो चिपकाते हैं, घटते क्रम में: कोई JWT, कोई Basic Auth हेडर, किसी webhook का payload, कोई कॉन्फ़िग फ़ाइल। चार में से तीन या तो ख़ुद क्रेडेंशियल हैं या उनके भीतर क्रेडेंशियल है। जो पन्ना इन्हें किसी सर्वर पर decode करता है, वह उन्हें देख चुका है — और वे उसके रिक्वेस्ट लॉग में हैं, कोई चाहे या न चाहे।

यह कोई किताबी आपत्ति नहीं है। यही वजह है कि इस पूरी क़िस्म की वेबसाइटें बहुत सी कंपनियों के प्रॉक्सी पर बंद हैं, और जहाँ बंद नहीं हैं वहाँ आम तौर पर कोई नीति मौजूद है जिसे कोई पढ़ता नहीं। इस पन्ने पर जो कुछ है वह ऐसा गणित है जो ब्राउज़र ख़ुद कर लेता है; उसे कहीं और भेजना एक फ़ैसला है, और वह ग़लत फ़ैसला है।

ब्राउज़र में असल में क्या रुकता है और क्या नहीं

पन्ना CDN से आने वाला स्थिर HTML है। पहली टाइप पर JavaScript का एक छोटा-सा हिस्सा लोड होता है, एक बार और उसके बाद कैश से, और काम आपके ही टैब में होता है। कोई भी रिक्वेस्ट आपका लिखा हुआ लेकर नहीं जाती, और इसे मान लेने के बजाय नेटवर्क पैनल में देख लेना बेहतर है।

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

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

डिजिटल पर्सनल डेटा प्रोटेक्शन ऐक्ट, 2023 उस पर बाध्यताएँ डालता है जो तय करता है कि निजी डेटा क्यों और कैसे प्रोसेस होगा। अगर डेटा डिवाइस से बाहर ही नहीं जाता, तो आपके चिपकाए हुए पर हमारे पास प्रोसेस करने को कुछ है ही नहीं — और व्यवहार में यही वह बिंदु है जहाँ बात तय होती है, जब खाने में कोई KYC रिकॉर्ड, कोई सपोर्ट संदेश या Aadhaar या PAN नंबर वाला payload पड़ा हो।

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

हर सवाल का अपना पन्ना, ड्रॉपडाउन वाला एक पन्ना नहीं

एक ही पन्ना जो किसी चुनने वाले खाने के पीछे Base64, URL और HTML को दोनों दिशाओं में निपटा देता, कम पन्ने होता और बुरा होता। Encode और decode अलग तरह से टूटते हैं, अलग तरह से समझाए जाते हैं और अलग तरह से खोजे जाते हैं: जिसके सामने टूटा हुआ percent sequence है और जो एक query बना रहा है, उन दोनों के पास एक-दूसरे से कहने को कुछ नहीं है।

इसलिए हर दिशा का अपना पन्ना है, अपनी ग़लतियों के साथ: Base64 जब टेक्स्ट नहीं बल्कि बाइट में खुले तो क्या करना है, `encodeURIComponent` विस्मयादिबोधक चिह्न को क्यों जाने देता है, और उससे किसी OAuth हस्ताक्षर का क्या बिगड़ता है। इससे ऐसा पन्ना बनता है जिसे पढ़ना बनता है, और यह सिर्फ़ इसलिए मुमकिन है कि वह एक साथ छह तरह के पाठकों को नहीं सँभाल रहा।

ये बिना इंटरनेट के भी चलते हैं

किसी औज़ार का पन्ना एक बार खुल जाने के बाद सब कुछ लोकल है: यह ट्रेन में चलता है, हवाई जहाज़ में चलता है, और उस कॉर्पोरेट प्रॉक्सी के पीछे भी चलता है जो एक घंटे बाद इस डोमेन को रोक दे। कोई service worker नहीं लगाया जाता और सेट करने को कुछ नहीं है; जो पन्ना कभी बाहर बात ही नहीं करता, उसके पास कनेक्शन जाने पर खोने को कुछ होता ही नहीं।

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

न खाता, न कोई सीमा, न वॉटरमार्क

पंजीकरण के लिए कुछ है ही नहीं क्योंकि सँभालने के लिए कुछ है ही नहीं। औज़ार दो मुलाक़ातों के बीच कुछ नहीं रखते: टैब बंद करते ही आपका लिखा मिट जाता है, क्योंकि वह उस टैब के अलावा कहीं मौजूद ही नहीं था।

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

तकनीकी शब्द अंग्रेज़ी में ही क्यों रहते हैं

इन पन्नों पर payload, token, hash, query string और Base64 लिखा है — «भार», «चिह्न», «सारांश» या «प्रश्न-शृंखला» नहीं। यह आलस नहीं है: भारतीय टीमों में इन चीज़ों की बात इसी भाषा में होती है और खोजा भी इसी में जाता है।

जहाँ रोज़मर्रा का हिंदी शब्द ही चलन में है, वहाँ वही लिखा है: बाइट के लिए बाइट, पर पन्ना, खाना, अक्षर, समय-क्षेत्र, जोड़ना, तोड़ना। नियम «जितनी हिंदी हो सके उतनी» नहीं है, नियम «बातचीत में जो शब्द बोला जाता है» है; बाक़ी कुछ भी करने से एक सही-सही अनूदित पन्ना बनता है जिस तक कोई पहुँचता नहीं।

हिंदी डेटा के साथ जो चीज़ें बार-बार टूटती हैं

तीन बातें इस पूरे परिवार में लौट-लौटकर आती हैं। पहली, देवनागरी का हर अक्षर UTF-8 में तीन बाइट लेता है, इसलिए अक्षरों में तय की गई हर सीमा हिंदी सामग्री पर तीन गुना तेज़ी से भरती है। दूसरी, Kruti Dev और उसी परिवार के फ़ॉन्ट में टाइप हुआ टेक्स्ट असल में ASCII बाइट है, इसलिए उसका hash, उसका Base64 और उसका hex किसी Unicode रूपांतरण से कभी नहीं मिलेंगे।

तीसरी सबसे चुपचाप काम करती है: zero-width joiner और non-joiner हिंदी टाइपिंग में आम हैं, कुछ दिखाते नहीं, और दो «एक जैसे» नामों को तुलना में अलग बना देते हैं। तीनों को पकड़ने की जगह एक ही है — hex वाला पन्ना, जहाँ बाइट सीधे दिखती हैं। इसीलिए यहाँ के दूसरे पन्ने संदेह होने पर उसी की ओर भेजते हैं।

यहाँ जान-बूझकर क्या नहीं है

HTML, CSS या JavaScript का कोई formatter यहाँ नहीं है, और यह एक फ़ैसला है, कमी नहीं। ठीक-ठाक काम करने वाले को असली parser चाहिए; इसके लिए इस्तेमाल होने वाली लाइब्रेरियाँ कई मेगाबाइट की हैं और वे लाइसेंस और लोड-समय दोनों का अपना फ़ैसला होतीं, जबकि घर का बना parser चुपचाप इनपुट बिगाड़ता है। JSON का formatter सिर्फ़ इसलिए बेख़तर है कि वह parser ब्राउज़र के भीतर पहले से मौजूद है।

Markdown या HTML की झलक भी नहीं है। दोनों का मतलब होता किसी और का HTML इसी पन्ने के भीतर रेंडर करना, और HTML entity decode वाला पन्ना ठीक इसी को तर्क के साथ मना करता है, क्योंकि ऐसा parser नेटवर्क रिक्वेस्ट करवा सकता है। जो दलील एक पन्ने पर चलती है उसे अगले पन्ने पर अनदेखा नहीं किया जा सकता।

डेवलपर के औज़ार: आम सवाल

मैं जो चिपकाता हूँ वह किसी सर्वर पर जाता है?

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

कितना टेक्स्ट चिपकाया जा सकता है, कोई सीमा है?

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

क्या मुझे खाता बनाना होगा?

नहीं, और बनाने को कुछ है भी नहीं। औज़ार दो मुलाक़ातों के बीच कुछ याद नहीं रखते: टैब बंद करते ही आपका लिखा मिट जाता है, क्योंकि वह कहीं और मौजूद ही नहीं था।

क्या मैं इसे अपनी कंपनी के डेटा के साथ इस्तेमाल कर सकता हूँ?

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

नतीजे से पहले डाउनलोड का क़दम क्यों नहीं है?

क्योंकि कोई फ़ाइल है ही नहीं। नतीजा पन्ने पर टेक्स्ट है, चुनने और कॉपी करने के लिए तैयार, और उससे पहले आपसे बटन दबवाकर कुछ हासिल नहीं होता। जहाँ कोई औज़ार सचमुच फ़ाइल बनाता है, वहाँ डाउनलोड आख़िर में है, पहले की रुकावट के रूप में नहीं।