URL decode करें

कोई URL या कोई मान चिपकाइए और पढ़िए कि percent शृंखलाओं के नीचे क्या लिखा है। जो एकमात्र असली दुविधा है वह विकल्प के रूप में सामने रखी जाती है: plus का चिह्न स्पेस है, जैसा फ़ॉर्म वाले query string में होता है, या सचमुच का plus, जैसा किसी path में। कुछ अपलोड नहीं होता, और यह मायने रखता है क्योंकि यहाँ चिपकाई जाने वाली URL लॉग से आती हैं और उनके बग़ल में session की पहचानें पड़ी होती हैं।

HTML फ़ॉर्म वाले query string स्पेस को + लिखते हैं। Path में plus सचमुच plus होता है।

नतीजा

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

  • कहाँ चलता है

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

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

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

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

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

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

  1. URL या encode किया हुआ मान चिपकाइए।
  2. Plus के चिह्न का बरताव चुनिए, इस हिसाब से कि स्ट्रिंग कहाँ से आई है।
  3. नतीजा पढ़िए। कुछ अपलोड नहीं हुआ है।

Plus का चिह्न ही असली फ़ैसला है

Query string में `+` लगभग हमेशा स्पेस होता है, क्योंकि HTML का फ़ॉर्म उसे ऐसे ही लिखता है। Path में नहीं: वहाँ वह एक अक्षर है, अपने-आप में। इसलिए वही स्ट्रिंग दो तरह से पढ़ी जाती है, इस पर निर्भर करके कि वह URL के किस हिस्से से आई है।

जो नतीजा चुभता है वह उन मानों में है जिनके भीतर असली plus हो: अंतरराष्ट्रीय रूप में लिखे मोबाइल नंबर और subaddress वाले ईमेल। भारतीय नंबर लगभग हमेशा `+91` से शुरू लिखा जाता है, और फ़ॉर्म वाले नियम से पढ़ने पर वह ` 91` बन जाता है — और गड़बड़ी बहुत बाद में, संदेश भेजते समय दिखती है, जहाँ कोई उसे कारण से जोड़ नहीं पाता।

ये बाइट हैं, अक्षर नहीं

हर `%` और उसके बाद के दो hexadecimal अंक एक बाइट हैं, और ASCII से बाहर के अक्षर कई बाइट लेते हैं: `%E0%A4%95` «क» है, `%E0%A4%A8` «न» है, और कोई emoji चार शृंखलाओं का होता है। Decode करना बाइट जोड़ना और फिर उन्हें UTF-8 की तरह पढ़ना है।

इसीलिए कोई अकेली शृंखला अवैध हो सकती है, भले अंक सही हों। हिंदी सामग्री में यह ख़ास तौर पर होता है, क्योंकि तीन में से एक भी शृंखला कट जाए तो बचा हुआ जोड़ा वैध UTF-8 नहीं बनता — और यहाँ यह कहा जाता है, बजाय ऐसा प्रतिस्थापन-चिह्न लौटाने के जो नतीजे जैसा दिखता। कटी हुई URL, ख़ासकर किसी लॉग की पंक्ति-सीमा पर कटी हुई, इसका सबसे आम स्रोत है।

दोहरी encoding decode करते समय दिखती है

अगर decode करने के बाद भी percent शृंखलाएँ बची रह जाएँ, तो स्ट्रिंग दो बार encode हुई थी। यह सही नतीजा है: एक चक्र `%2520` को `%20` में बदलता है, और जो औज़ार तब तक decode करता रहे जब तक कुछ न बचे वह उन मानों को नष्ट कर देता जिनमें असली `%` है।

हल यह नहीं है कि इसे नियमित रूप से यहाँ दो बार चलाया जाए, बल्कि यह कि अपनी प्रक्रिया-शृंखला में वह चरण ढूँढ़ा जाए जो पहले से encode हुई चीज़ को दोबारा encode कर रहा है — लगभग हमेशा कोई framework जो यह आपके लिए करता है और कोई template जो उसे दोहरा देता है।

पूरी URL decode करना उसे तोड़ सकता है

अगर आप पूरा पता decode करते हैं तो `%2F` तिरछी लकीरें बन जाती हैं और `%3F` प्रश्नचिह्न, और नतीजे का ढाँचा वही नहीं रह जाता: जो एक मान था वह अब कोई path या कोई नया query string जैसा दिखने लगता है।

यह पढ़ने के लिए काम का है और दोबारा इस्तेमाल के लिए ख़तरनाक। खुला redirect ठीक इसी तरह बनता है — हमलावर encode की गई URL को मान की तरह डालता है और कोई चीज़ उसे जाँचने से पहले decode कर देती है। नियम यह है: देखने के लिए decode कीजिए और जाँच हमेशा मूल रूप पर कीजिए।

Fragment लॉग में आता ही नहीं

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

Analytics के निर्यात में वह दिख सकता है, क्योंकि वहाँ उसे वह स्क्रिप्ट लिखती है जो उसे देखती है। आप जिस स्रोत से आई स्ट्रिंग देख रहे हैं, वह बदल देता है कि उससे क्या निष्कर्ष निकाला जा सकता है, और यही वह ब्योरा है जो एक घंटे की उलझन बचा देता है।

किसी पैरामीटर में आम तौर पर क्या होता है

खोज-शब्द, redirect की मंज़िलें, ईमेल पते, पुष्टि के token और UTM पैरामीटर। पहले तीन अक्सर निजी डेटा होते हैं, और चौथा एक बार इस्तेमाल होने वाली credential है।

उनका encode होना उन्हें किसी चीज़ से नहीं बचाता: percent encoding किसी के लिए भी पढ़ने लायक़ है, और वह स्ट्रिंग सर्वर के लॉग में, ब्राउज़र के इतिहास में और अगले क्लिक के referrer हेडर में मौजूद है। अगर यहाँ आपको कोई ऐसी चीज़ निकले जो रहस्य जैसी लगती है, तो खोज वही है — यह नहीं कि उसे decode किया जा सका।

UTM पैरामीटर और वे क्यों निरापद हैं

`utm_source`, `utm_medium`, `utm_campaign`, `utm_term` और `utm_content` Urchin से आते हैं, उसी औज़ार से जिससे Google Analytics निकला। सर्वर पर वे कुछ नहीं करते: वे टेक्स्ट हैं जिन्हें ब्राउज़र में कोई माप वाली स्क्रिप्ट पढ़ती है।

चूँकि वे कुछ करते नहीं, कोई लिंक आगे भेजते समय उन्हें बिना किसी नतीजे के हटाया जा सकता है, अगर आप भेजने वाले के आँकड़ों में अपना अग्रेषण मिलाना नहीं चाहते। और चूँकि वे पते में रहते हैं, वे इतिहास में, साझा किए गए लिंक में और bookmark में पहुँच जाते हैं — यही वजह है कि newsletter के कुछ लिंक बेतुके ढंग से लंबे होते हैं।

%u0915 जैसी शृंखलाएँ यहाँ क्यों नहीं चलतीं

अगर आपकी स्ट्रिंग में `%u0915` जैसा कुछ है तो वह percent encoding नहीं है। वह JavaScript के पुराने `escape()` फलन का बनाया रूप है, जो अक्षर का code point सीधे लिख देता था, और वह किसी URL मानक का हिस्सा कभी नहीं रहा।

यह हिंदी डेटा में औसत से ज़्यादा मिलता है, क्योंकि `escape()` ASCII से बाहर की हर चीज़ के लिए यही करता था और पुराने भारतीय पन्नों का JavaScript अक्सर वैसा ही चल रहा है। यह decoder उसे नहीं खोलता और यह जान-बूझकर है: `%u` वाली स्ट्रिंग को चुपचाप ठीक कर देना उस दोष को छिपा देता जिसे आपको उसके स्रोत पर सुधारना है।

यहाँ न झलक है, न कुछ खोला जाता है

यहाँ decode होता है, दौरा नहीं। Host को कोई रिक्वेस्ट नहीं जाती, redirect हल नहीं किए जाते और कोई पूर्वावलोकन नहीं है, और यह एक फ़ैसला है: जो किसी संदिग्ध URL की जाँच कर रहा है वह सबसे आख़िरी व्यक्ति है जो चाहेगा कि औज़ार उसे खोल दे।

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

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

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

यही वह बात है जो ऐसे निर्यात को किसी ऑनलाइन औज़ार से देखना संभव बनाती है। जो सेवा दूर किसी सर्वर पर decode करती वह वह पंक्ति पा चुकी होती और वह उसके लॉग में होती — और अधिकतर आंतरिक नीतियाँ ठीक इसी हालत को रोकने के लिए बनी होती हैं।

URL decode करें: आम सवाल

क्या मुझे + को स्पेस मानना चाहिए?

अगर स्ट्रिंग किसी query string से आई है तो लगभग तय रूप से हाँ: HTML फ़ॉर्म स्पेस को + लिखते हैं। अगर वह किसी path से आई है तो नहीं, क्योंकि वहाँ plus सचमुच plus है। इसीलिए यह विकल्प है, धारणा नहीं।

Decode करने के बाद भी %20 बचे हैं, ऐसा क्यों?

क्योंकि स्ट्रिंग दो बार encode हुई थी: उसमें %2520 था। एक चक्र का यही सही नतीजा है। सुधार आपकी प्रक्रिया-शृंखला के उस चरण में करना है जो पहले से encode हुई चीज़ को दोबारा encode करता है।

देखने में ठीक लगने वाली शृंखला विफल क्यों होती है?

क्योंकि उससे बनी बाइट वैध UTF-8 नहीं हैं। हिंदी में यह अक्सर तब होता है जब तीन शृंखलाओं में से एक कट गई हो, जैसे किसी लॉग की पंक्ति-सीमा पर। यह कहा जाता है, बजाय प्रतिस्थापन-चिह्न लौटाने के।

क्या पता खोला जाता है?

नहीं। यहाँ decode होता है, दौरा नहीं: न host को कोई रिक्वेस्ट, न पूर्वावलोकन, न redirect का हल। किसी संदिग्ध या एक बार इस्तेमाल होने वाली URL के साथ यही सबसे ज़रूरी बात है।

क्या स्ट्रिंग मेरे डिवाइस से बाहर जाती है?

नहीं। Decoding इसी पन्ने पर होती है। यह मायने रखता है क्योंकि लॉग से आई URL के बग़ल में session की पहचानें, token और कभी-कभी ईमेल पते पड़े होते हैं।

और टूल्स