PHP में रैंडम स्ट्रिंग जनरेटर वास्तव में कैसे काम करता है? हुड के नीचे झाँकना
\n\nक्या आपने कभी सोचा है कि जब आप किसी वेबसाइट पर "पासवर्ड जनरेट करें" पर क्लिक करते हैं तो क्या होता है? या जब सिस्टम आपके सत्र के लिए एक अद्वितीय पहचानकर्ता बनाता है? दस में से नौ मामलों में, इसके पीछे PHP में रैंडम स्ट्रिंग जनरेटर होता है। यह कितना आसान लगता है: कैरेक्टर का एक ऐरे लिया, उसे फेरबदल किया, और परिणाम दिया। लेकिन शैतान, हमेशा की तरह, विवरणों में छिपा है।
\n\nStack Overflow पर, "PHP random string generator" प्रश्न ने हज़ारों बार देखा गया है। और यह कोई संयोग नहीं है। शुरुआती लोग rand() के साथ पहिए का पुनः आविष्कार करते हैं, अनुभवी लोग random_int() का उपयोग करते हैं, और गुरु एंट्रॉपी पर बहस करते हैं। आइए समझें कि यह वास्तव में कैसे काम करता है, और अपना आदर्श जनरेटर लिखें।
rand() बुरा क्यों है? (स्पॉयलर: पूर्वानुमानशीलता)
\n\nसबसे लोकप्रिय "बचकाना" तरीका लूप में rand() का उपयोग करना है:
<?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}\necho generateRandomString(); // आउटपुट: "aB3kL9xQ2m"\n?>\n\nकोड काम करता है। लेकिन केवल तभी जब आपको सुरक्षा की परवाह न हो। rand() फंक्शन लीनियर कॉन्ग्रुएंशियल जनरेटर (LCG) का उपयोग करता है। यह एक नियतात्मक एल्गोरिथम है: वर्तमान स्थिति जानकर, आप सभी अगली संख्याओं का पूर्वानुमान लगा सकते हैं। इसके अलावा, rand() डिफ़ॉल्ट रूप से एक से इनिशियलाइज़ होता है, जब तक कि आपने srand() को कॉल नहीं किया। और यदि कॉल किया, तो seed अक्सर time() से लिया जाता है, जो केवल 2-3 मिलियन विकल्प देता है। ब्रूट-फोर्स में सेकंड लगते हैं।
निष्कर्ष: rand() गेम और रैंडम अवतार चयन के लिए ठीक है, लेकिन टोकन, पासवर्ड या API कुंजियाँ जनरेट करने के लिए बिल्कुल उपयुक्त नहीं है।
mt_rand() से मिलिए — तेज़, लेकिन अधिक सुरक्षित नहीं
\n\nPHP 4 में mt_rand() आया, जो मेरसेन ट्विस्टर (Mersenne Twister) पर आधारित है। यह तेज़ है और इसकी अवधि बेहतर है (rand के 2^31 की तुलना में 2^19937)। कई लोग अभी भी इसे "उन्नत" संस्करण के रूप में उपयोग करते हैं:
<?php\nfunction generateTokenMtRand($length = 32) {\n $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n $token = '';\n for ($i = 0; $i < $length; $i++) {\n $token .= $chars[mt_rand(0, strlen($chars) - 1)];\n }\n return $token;\n}\n?>\n\nलेकिन यहाँ भी एक खामी है। मेरसेन ट्विस्टर क्रिप्टोग्राफिक रूप से सुरक्षित नहीं है। 624 जनरेटेड संख्याओं के अनुक्रम से, जनरेटर की आंतरिक स्थिति को पुनर्स्थापित किया जा सकता है और सभी भविष्य के मानों का पूर्वानुमान लगाया जा सकता है। पासवर्ड रीसेट टोकन पर हमला करने के लिए यह पर्याप्त से अधिक है।
\n\nनैतिकता: mt_rand() सिमुलेशन और परीक्षणों के लिए एक उत्कृष्ट विकल्प है, लेकिन सुरक्षा के लिए नहीं।
पवित्र त्रिमूर्ति: random_int(), CSPRNG और एंट्रॉपी
\n\nPHP 7.0 से शुरू करके, हमारे पास random_int() और random_bytes() हैं। ये क्रिप्टोग्राफिक रूप से सुरक्षित स्यूडो-रैंडम नंबर जनरेटर (CSPRNG) हैं। व्यवहार में इसका क्या अर्थ है?
- \n
- एंट्रॉपी: PHP सिस्टम से "शोर" एकत्र करता है: कीस्ट्रोक्स के बीच का समय, माउस मूवमेंट, नेटवर्क पैकेट, डिस्क इंटरप्ट। Linux में
/dev/urandomका उपयोग किया जाता है, Windows मेंCryptGenRandomका। \n - अप्रत्याशितता: एल्गोरिथम जानने के बावजूद, seed को पुनर्स्थापित नहीं किया जा सकता या अगली संख्या का पूर्वानुमान नहीं लगाया जा सकता। \n
- समान वितरण: प्रत्येक बाइट ठीक 1/256 की संभावना के साथ आता है। \n
PHP में सही रैंडम स्ट्रिंग जनरेटर इस प्रकार दिखता है