PHP random string generator: अंदर कैसे काम करता है
\n\nहर डेवलपर को कभी न कभी रैंडम स्ट्रिंग बनाने की ज़रूरत पड़ती है। टोकन, अस्थायी पासवर्ड, सेशन ID या टेस्ट डेटा के लिए। PHP में ऐसा करने के दसियों तरीके हैं, लेकिन कौन सा सही है? और सबसे ज़रूरी — क्यों?
\n\nStack Overflow पर 'PHP random string generator' सवाल को हज़ारों बार देखा गया है और सैकड़ों जवाब मिले हैं। लेकिन ज़्यादातर जवाब बिना समझाए सिर्फ कोड स्निपेट होते हैं। आज हम PHP के अंदर झाँकेंगे और समझेंगे कि random string generator असल में कैसे काम करते हैं, rand() और random_int() में क्या फर्क है, और आपका 'रैंडम' पासवर्ड बिल्कुल रैंडम क्यों नहीं हो सकता।
PHP में 'रैंडमनेस' क्या है?
\n\nप्रोग्रामिंग में रैंडमनेस दो तरह की होती है: स्यूडो-रैंडमनेस और क्रिप्टोग्राफिक रैंडमनेस। इनमें फर्क एक पासा फेंकने और एक पूर्वानुमानित कैलकुलेटर के बीच जैसा है।
\n\nस्यूडो-रैंडम नंबर (PRNG) एक एल्गोरिदम द्वारा एक सीड (seed) के आधार पर जनरेट होते हैं। अगर आप सीड जानते हैं, तो पूरा सीक्वेंस जान सकते हैं। सामान्य कामों (जैसे डिज़ाइन में रंग रैंडम करना, टेस्ट डेटा) के लिए यह काफी है। लेकिन ऑथेंटिकेशन टोकन और पासवर्ड के लिए — यह आपदा है।
\n\nPHP कई फंक्शन देता है, और हर एक 'रैंडमनेस' का अलग स्तर है:
\n\n- \n
rand()— क्लासिक PRNG, तेज़ लेकिन पूर्वानुमानित \n mt_rand()— बेहतर Mersenne Twister एल्गोरिदम, तेज़ और लंबी अवधि वाला \n random_int()औरrandom_bytes()— क्रिप्टोग्राफिक जनरेटर (PHP 7+) \n openssl_random_pseudo_bytes()— एक और क्रिप्टोग्राफिक विकल्प \n
सबसे लोकप्रिय स्निपेट कैसे काम करता है?
\n\nयह क्लासिक कोड है जो इंटरनेट पर मिलता है:
\n\n<?php\nfunction generateRandomString($length = 10) {\n $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n $charactersLength = strlen($characters);\n $randomString = '';\n for ($i = 0; $i < $length; $i++) {\n $randomString .= $characters[rand(0, $charactersLength - 1)];\n }\n return $randomString;\n}\n?>\n\nपहली नज़र में सब ठीक लगता है। एक स्ट्रिंग लेते हैं, बेतरतीब इंडेक्स चुनते हैं, दोहराते हैं। लेकिन देखते हैं असल में क्या हो रहा है।
\n\nसमस्या #1: rand() और इसका सीड
\n\nPHP में rand() फंक्शन डिफ़ॉल्ट रूप से Linear Congruential Generator (LCG) एल्गोरिदम का उपयोग करता है। यह सबसे पुराने और सबसे पूर्वानुमानित तरीकों में से एक है। अगर आपने srand() को रैंडम सीड के साथ कॉल नहीं किया, तो PHP ऑटोमैटिकली जनरेटर को वर्तमान समय (माइक्रोसेकंड में) से इनिशियलाइज़ करता है।
अगर कोई हमलावर स्क्रिप्ट के शुरू होने का सही समय जानता है (जैसे सर्वर लॉग से), तो वह पूरे rand() सीक्वेंस को दोबारा बना सकता है। पासवर्ड रिकवरी टोकन के लिए — यह हैकिंग का सीधा रास्ता है।
समस्या #2: संभावना में असंतुलन (Bias)
\n\nसुरक्षा को छोड़ भी दें, तो एक गणितीय समस्या है। मान लीजिए rand(0, 61) (स्ट्रिंग में 62 कैरेक्टर)। PHP आंतरिक रूप से 0 से getrandmax() (आमतौर पर 2147483647) तक की रेंज का उपयोग करता है। 2147483647, 62 से पूरी तरह विभाजित नहीं होता। शेष 31 बचता है। इसका मतलब है कि रेंज के पहले 31 नंबरों के आने की संभावना बाकियों से थोड़ी ज़्यादा है।
व्यवहार में यह अंतर बहुत छोटा है, लेकिन अगर आपको समान रूप से वितरित रैंडम स्ट्रिंग चाहिए, तो rand() सबसे अच्छा विकल्प नहीं है। random_int() इस समस्या को हल करता है, क्योंकि यह एक एल्गोरिदम का उपयोग करता है जो समान वितरण सुनिश्चित करता है।
क्रिप्टोग्राफिक जनरेटर: अंदर क्या है?
\n\nPHP 7 में random_int() और random_bytes() फंक्शन आए। ये सिस्टम के एंट्रॉपी स्रोत का उपयोग करते हैं: