यादृच्छिक 5 वर्ण स्ट्रिंग उत्पन्न करें


102

मैं सटीक 5 यादृच्छिक वर्ण स्ट्रिंग बनाना चाहता हूं जिसकी नकल होने की कम से कम संभावना है। इसे करने का सबसे अच्छा तरीका क्या होगा? धन्यवाद।


2
क्या आपके पास एक विशिष्ट वर्ण या केवल एक सेट है 0-9a-zA-Z?
यानिक रोचोन

यह कोड गोल्फ चुनौती एक खोज हो सकती है: codegolf.stackexchange.com/questions/119226/…
टाइटस

का उपयोग करके Random::alphanumericString($length)आप 0-9a-zA-Z के साथ तार प्राप्त कर सकते हैं जो क्रिप्टोग्राफिक रूप से सुरक्षित यादृच्छिक डेटा से sourced हैं।
caw

जवाबों:


162
$rand = substr(md5(microtime()),rand(0,26),5);

मेरा सबसे अच्छा अनुमान होगा - जब तक आप विशेष पात्रों की तलाश में न हों, तब भी:

$seed = str_split('abcdefghijklmnopqrstuvwxyz'
                 .'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
                 .'0123456789!@#$%^&*()'); // and any other characters
shuffle($seed); // probably optional since array_is randomized; this may be redundant
$rand = '';
foreach (array_rand($seed, 5) as $k) $rand .= $seed[$k];

उदाहरण

और, घड़ी के आधार पर एक के लिए (कम वृद्धि के बाद से यह वृद्धिशील है):

function incrementalHash($len = 5){
  $charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  $base = strlen($charset);
  $result = '';

  $now = explode(' ', microtime())[1];
  while ($now >= $base){
    $i = $now % $base;
    $result = $charset[$i] . $result;
    $now /= $base;
  }
  return substr($result, -5);
}

नोट: वृद्धिशील का मतलब अनुमान लगाना आसान है; यदि आप इसे नमक या सत्यापन टोकन के रूप में उपयोग कर रहे हैं, तो न करें। "WCWyb" के एक नमक (अब) का अर्थ है अब से 5 सेकंड "WCWyg")


6
का उपयोग कर के साथ समस्या यह md5()तथापि है कि आप एक स्ट्रिंग 16-वर्ण सेट से बना (10 अंक और मिलता है aकरने के लिए f, यानी स्ट्रिंग चरित्र प्रति 4 बिट्स)। यह कुछ उद्देश्यों के लिए पर्याप्त हो सकता है लेकिन क्रिप्टोग्राफ़िक उद्देश्यों के लिए बहुत कम हो सकता है (16 प्रतीकों में से पांच वर्ण = 16 ^ 5 = 20 बिट्स = 1048576 संभावनाएं)।
आर्क

3
array_rand($seed, 5)सरणी कुंजी को लौटाएगा, मान नहीं, इसलिए आपका कोड काम नहीं करेगा
अलुमी

1
मुझे लगता है कि यादृच्छिक वर्ण उत्पन्न करने के लिए एक क्रिप्टोग्राफ़िक हैश फ़ंक्शन का उपयोग करना कम से कम अनुचित है।
ग्रोनोस्तज

यह संभव भी शामिल करने के लिए है ", 'में और बैकस्लैश $charset? क्या मुझे उन पात्रों को शामिल करने के लिए एस्केप सीक्वेंस का उपयोग करने की आवश्यकता है?
माई

1
दूसरा स्निपेट भी $lenइनपुट परम का उपयोग नहीं करता है ... क्या आप इसे भूल गए?
TechNyquist

76

यदि forलूप कम आपूर्ति पर हैं, तो यहां मुझे क्या उपयोग करना है:

$s = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);

दिलचस्प समाधान ... बहुत संक्षिप्त, हालांकि मुझे आश्चर्य है कि क्या यह उपयोग करने की तुलना में तेज या धीमा है। हालांकि बेंचमार्क के लिए परेशान नहीं किया जा सकता है :-)
आर्क

@ मट्टू str_shuffle डुप्लिकेट लगातार उत्पादन करेगा
SCC

@ user2826057: str_shuffle('ab')देगा abया baकभी नहीं aa। उसके लिए str_repeatअनुमति जोड़ना । लेकिन उस ने कहा, मैंने जो समाधान दिया वह वास्तव में गंभीर नहीं है ... हालांकि यह काम करता है।
मैथ्यू

2
ऐसा होने का 1/60466176 मौका है, मान लें कि आरएनजी समान रूप से वितरित की गई है।
मैथ्यू

1
वाउचर कोड जनरेट करने के हमारे उपयोग के मामले में यह सही है। हम वर्ण, जैसे भ्रामक हटाया l, i, 1, 0, O, आदि और बाहर के 500 वाउचर कोई डुप्लिकेट मिला है।
ल्यूक कजिन



15

निम्नलिखित को दोहराव का कम से कम मौका देना चाहिए (आप mt_rand()एक बेहतर यादृच्छिक संख्या स्रोत जैसे /dev/*randomकि GUID से या उससे बदलना चाह सकते हैं ):

<?php
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $result = '';
    for ($i = 0; $i < 5; $i++)
        $result .= $characters[mt_rand(0, 61)];
?>

संपादित करें:
यदि आप सुरक्षा के बारे में चिंतित हैं, तो वास्तव में, उपयोग करें rand()या mt_rand()यह सत्यापित करें कि आपका यादृच्छिक डेटा डिवाइस वास्तव में एक यादृच्छिक डेटा बनाने वाला उपकरण है , न कि एक नियमित फ़ाइल या कुछ पूर्वानुमान जैसा /dev/zeromt_rand()हानिकारक माना जाता है:
https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php

संपादित करें: यदि आपके पास PHP में OpenSSL का समर्थन है, तो आप उपयोग कर सकते हैं openssl_random_pseudo_bytes():

<?php
    $length = 5;
    $randomBytes = openssl_random_pseudo_bytes($length);
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $charactersLength = strlen($characters);
    $result = '';
    for ($i = 0; $i < $length; $i++)
        $result .= $characters[ord($randomBytes[$i]) % $charactersLength];
?>

पहले उदाहरण $ परिणाम के साथ अधिक चतुर = $ वर्ण [mt_rand (0, strlen ($ वर्ण) -1)]।
hamboy75

उस मामले में आपको पहले से लंबाई निर्धारित करनी चाहिए और इसे कम से कम एक चर में संग्रहीत करना चाहिए। strlen()लूप में उपयोग करना अनावश्यक ओवरहेड है, खासकर यदि आप पहले से ही जानते हैं कि इस बीच वर्ण सेट बदलने वाला नहीं है।
आर्क

मुझे संदेह है, php अनुकूलित है, वैसे भी यह एक विकल्प है :)
hamboy75

7

मैं हमेशा इसके लिए एक ही फ़ंक्शन का उपयोग करता हूं, आमतौर पर पासवर्ड उत्पन्न करने के लिए। यह प्रयोग करने में आसान और उपयोगी है।

function randPass($length, $strength=8) {
    $vowels = 'aeuy';
    $consonants = 'bdghjmnpqrstvz';
    if ($strength >= 1) {
        $consonants .= 'BDGHJLMNPQRSTVWXZ';
    }
    if ($strength >= 2) {
        $vowels .= "AEUY";
    }
    if ($strength >= 4) {
        $consonants .= '23456789';
    }
    if ($strength >= 8) {
        $consonants .= '@#$%';
    }

    $password = '';
    $alt = time() % 2;
    for ($i = 0; $i < $length; $i++) {
        if ($alt == 1) {
            $password .= $consonants[(rand() % strlen($consonants))];
            $alt = 0;
        } else {
            $password .= $vowels[(rand() % strlen($vowels))];
            $alt = 1;
        }
    }
    return $password;
}

अच्छा कोड है। हालाँकि, $ alt हमेशा एक से 0. तक फ़्लिप करता है, क्या इसके बजाय $ alt को यादृच्छिक बनाना बेहतर नहीं होगा?
निको एंड्रेड

6

ऐसा लगता है कि str_shuffle इसके लिए एक अच्छा उपयोग होगा। जो भी आप चाहते हैं पात्रों के साथ फेरबदल बीज।

$my_rand_strng = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), -5);

php टी करने के लिए दोनों अच्छे अप: php.net/manual/en/function.substr.php php.net/manual/en/function.str-shuffle.php
Creeperstanson

3
$str = '';
$str_len = 8;
for($i = 0, $i < $str_len; $i++){
    //97 is ascii code for 'a' and 122 is ascii code for z
    $str .= chr(rand(97, 122));
}
return $str

2

यदि यह ठीक है कि आपको केवल AF पत्र मिलेगा, तो यहाँ मेरा समाधान है:

str_pad(dechex(mt_rand(0, 0xFFFFF)), 5, '0', STR_PAD_LEFT);

मेरा मानना ​​है कि हैश फ़ंक्शन का उपयोग करना यादृच्छिक हेक्साडेसिमल अंकों के अनुक्रम को उत्पन्न करने के लिए इस तरह के एक सरल कार्य के लिए एक ओवरकिल है। dechex+ mt_randवही काम करेगा, लेकिन बिना अनावश्यक क्रिप्टोग्राफिक के काम करेगा। str_padआउटपुट स्ट्रिंग की 5-वर्ण लंबाई की गारंटी देता है (यदि यादृच्छिक संख्या 0x10000 से कम है)।

डुप्लिकेट संभावना mt_randविश्वसनीयता पर निर्भर करती है । मेरसेन ट्विस्टर उच्च गुणवत्ता वाले यादृच्छिकता के लिए जाना जाता है, इसलिए इसे कार्य को अच्छी तरह से फिट करना चाहिए।


2

मुझे यह भी नहीं पता था कि यह कैसे करना है जब तक कि मैंने PHP के उपयोग के बारे में नहीं सोचा था array। और मुझे पूरा यकीन है कि यह सरणी के साथ एक यादृच्छिक स्ट्रिंग या संख्या उत्पन्न करने का सबसे सरल तरीका है। कोड:

function randstr ($len=10, $abc="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789") {
    $letters = str_split($abc);
    $str = "";
    for ($i=0; $i<=$len; $i++) {
        $str .= $letters[rand(0, count($letters)-1)];
    };
    return $str;
};

आप इस फ़ंक्शन का उपयोग इस तरह कर सकते हैं

randstr(20)     // returns a random 20 letter string
                // Or like this
randstr(5, abc) // returns a random 5 letter string using the letters "abc"

1

करने के लिए इसी तरह के ब्रैड क्रिस्टी के जवाब है, लेकिन का उपयोग कर sha1पात्रों के लिए alrorithm 0-9a-zA-Zऔर एक यादृच्छिक मूल्य के साथ उपसर्ग:

$str = substr(sha1(mt_rand() . microtime()), mt_rand(0,35), 5);

लेकिन अगर आपने एक निर्धारित (अनुमत) वर्ण निर्धारित किया है:

$validChars = array('0','1','2' /*...*/,'?','-','_','a','b','c' /*...*/);
$validCharsCount = count($validChars);

$str = '';
for ($i=0; $i<5; $i++) {
    $str .= $validChars[rand(0,$validCharsCount - 1)];
}

** अद्यतन **

जैसा कि आर्किमिडिक्स ने बताया है, यह "डुप्लिकेट होने की कम से कम संभावना" वापस करने की गारंटी नहीं देगा क्योंकि दी गई वर्ण सीमा के लिए संयोजन की संख्या कम है। आपको या तो वर्णों की संख्या बढ़ाने की आवश्यकता होगी, या स्ट्रिंग में अतिरिक्त (विशेष) वर्णों को अनुमति देने की आवश्यकता होगी। पहला उपाय बेहतर होगा, मुझे लगता है, आपके मामले में।


की time()तुलना में 1 मिलियन गुना अधिक अनुमानित है microtime()
आर्क

ब्रैड के उत्तर पर मेरी टिप्पणियों पर भी ध्यान दें, इससे भी बड़ा मुद्दा यह है कि जेनरेट किया गया हैश एक हेक्साडेसिमल प्रतिनिधित्व है जिसमें 16 मान्य वर्ण शामिल हैं, इसलिए केवल 1024 भिन्नताएं हैं $str
आर्क

@Archimedix, शायद, लेकिन ओपी ने सुरक्षा नहीं मांगी, इस सवाल को परिभाषित किया गया था कि स्ट्रिंग जनरेटिंग एल्गोरिथ्म में 5x26 विभिन्न वर्णों का संयोजन है, और डुप्लिकेट से बचने के लिए। यह शायद एक पंजीकरण प्रक्रिया (या बिलिंग प्रक्रिया), या कुछ और में
यनिक्क रोचोन

यह मेरी समझ है कि वह किया था के लिए पूछना दोहराया होने का कम से कम संभावना है, और इस 0.1% संभावना (1024 में 1) 1 अरब में लगभग 1 हो सकता था जो है।
आर्क

हालाँकि, यदि आपको 5 वर्णों की संदर्भ कुंजी उत्पन्न करनी है और आपको ग्राहक / ग्राहक देना है, तो आप उन्हें नहीं देना चाहते " ˫§»⁋⅓" क्योंकि यह अधिक सुरक्षित है ... आप अपनी संदर्भ कुंजी को 7 या अधिक वर्णों तक बढ़ाते हैं। । (BTW: मेरी पिछली टिप्पणी में सुधार, यह 5x36 अक्षर है)
यानिक


1

स्रोत: PHP फ़ंक्शन जो यादृच्छिक वर्ण उत्पन्न करता है

यह सरल PHP फ़ंक्शन मेरे लिए काम करता है:

function cvf_ps_generate_random_code($length=10) {

   $string = '';
   // You can define your own characters here.
   $characters = "23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";

   for ($p = 0; $p < $length; $p++) {
       $string .= $characters[mt_rand(0, strlen($characters)-1)];
   }

   return $string;

}

उपयोग:

echo cvf_ps_generate_random_code(5);

1

यहाँ मेरे हैं random 5 cents...

$random=function($a, $b) {
    return(
        substr(str_shuffle(('\\`)/|@'.
        password_hash(mt_rand(0,999999),
        PASSWORD_DEFAULT).'!*^&~(')),
        $a, $b)
    );
};

echo($random(0,5));

PHP का नया password_hash()(*> = PHP 5.5) फंक्शन पीढ़ी दर पीढ़ी अपरकेस और लोअरकेस कैरेक्टर्स और नंबरों के सेट के लिए काम कर रहा है।

दो समास। password_hash$ यादृच्छिक कार्य के पहले और बाद के तार परिवर्तन के लिए उपयुक्त हैं।

Paramteres के लिए $random()* ($ a, $ b) वास्तव में substr()पैरामीटर हैं। :)

नोट: यह एक समारोह होने की जरूरत नहीं है, यह सामान्य चर के रूप में अच्छी तरह से किया जा सकता है .. इस तरह एक बुरा एकललाइनर के रूप में:

$random=(substr(str_shuffle(('\\`)/|@'.password_hash(mt_rand(0,999999), PASSWORD_DEFAULT).'!*^&~(')), 0, 5));

echo($random);

1
function CaracteresAleatorios( $Tamanno, $Opciones) {
    $Opciones = empty($Opciones) ? array(0, 1, 2) : $Opciones;
    $Tamanno = empty($Tamanno) ? 16 : $Tamanno;
    $Caracteres=array("0123456789","abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    $Caracteres= implode("",array_intersect_key($Caracteres, array_flip($Opciones)));
    $CantidadCaracteres=strlen($Caracteres)-1;
    $CaracteresAleatorios='';
    for ($k = 0; $k < $Tamanno; $k++) {
        $CaracteresAleatorios.=$Caracteres[rand(0, $CantidadCaracteres)];
    }
    return $CaracteresAleatorios;
}

प्रो टिप - अपने उत्तर की ओपी समस्या को हल करने के तरीके के बारे में कुछ स्पष्टीकरण शामिल करें, और यह पहले से उपलब्ध अन्य उत्तरों के लिए अलग क्यों हो सकता है।
टॉम

0

मैं इसका उपयोग करता हूं:

<?php function fRand($len) {
    $str = '';
    $a = "abcdefghijklmnopqrstuvwxyz0123456789";
    $b = str_split($a);
    for ($i=1; $i <= $len ; $i++) { 
        $str .= $b[rand(0,strlen($a)-1)];
    }
    return $str;
} ?>

जब आप इसे कॉल करते हैं, तो स्ट्रिंग की लेन सेट करता है।

<?php echo fRand([LENGHT]); ?>

आप स्ट्रिंग में संभावित वर्ण भी बदल सकते हैं $a


मैं देख रहा हूं कि इस समारोह को विकसित करने में समय नष्ट हो गया। मैं थोड़ा गूँज गया! @ और
लिपसेरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.