提问



我试图在PHP中创建一个随机字符串,我绝对没有输出:


<?php
function RandomString()
{
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randstring = '';
    for ($i = 0; $i < 10; $i++) {
        $randstring = $characters[rand(0, strlen($characters))];
    }
    return $randstring;
}
RandomString();
echo $randstring;


我究竟做错了什么?

最佳参考


要具体回答这个问题,有两个问题:



    当你回应时,
  1. $randstring不在范围内。

  2. 字符不会在循环中连接在一起。



这是一个带有更正的代码片段:


function generateRandomString($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}


使用以下调用输出随机字符串:


// Echo the random string.
// Optionally, you can give it a desired string length.
echo generateRandomString();



  请注意,这会产生可预测的随机字符串。如果您想创建安全令牌,请参阅此答案。


其它参考1



  注意:str_shuffle()内部使用rand(),这不适用于加密目的(例如生成随机密码)。你想要一个安全的随机数发生器。它也不允许字符重复。[72]



还有一种方法。



更新 (现在生成任意长度的字符串):


function generateRandomString($length = 10) {
    return substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
}

echo  generateRandomString();  // OR: generateRandomString(24)


而已。 :)

其它参考2


这个问题有很多答案,但没有一个利用密码安全伪随机数发生器(CSPRNG)。[74]


简单,安全和正确的答案是使用RandomLib并且不要重新发明轮子。[75]


对于那些坚持发明自己的解决方案的人,PHP 7.0.0将为此目的提供random_int();如果您仍然使用PHP 5.x,我们为random_int()编写了一个PHP 5 polyfill,这样您甚至可以在升级到PHP 7之前使用新的API。[76] [77]


在PHP中安全地生成随机整数并不是一项简单的任务。在生产中部署自行生成的算法之前,应始终与驻地StackExchange加密专家核实。[78] [79]


使用安全的整数生成器,生成带有CSPRNG的随机字符串就是在公园散步。


创建安全的随机字符串



/**
 * Generate a random string, using a cryptographically secure 
 * pseudorandom number generator (random_int)
 * 
 * For PHP 7, random_int is a PHP core function
 * For PHP 5.x, depends on https://github.com/paragonie/random_compat
 * 
 * @param int $length      How many characters do we want?
 * @param string $keyspace A string of all possible characters
 *                         to select from
 * @return string
 */
function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    $pieces = [];
    $max = mb_strlen($keyspace, '8bit') - 1;
    for ($i = 0; $i < $length; ++$i) {
        $pieces []= $keyspace[random_int(0, $max)];
    }
    return implode('', $pieces);
}


用法:


$a = random_str(32);
$b = random_str(8, 'abcdefghijklmnopqrstuvwxyz');


演示:https://3v4l.org/b4PST(忽略PHP 5失败;需要random_compat)[80]

其它参考3


创建一个20 char长的hexdec字符串:


$string = bin2hex(openssl_random_pseudo_bytes(10)); // 20 chars


在PHP 7中(random_bytes()):[81]


$string = base64_encode(random_bytes(10)); // ~14 chars
// or
$string = bin2hex(random_bytes(10)); // 20 chars

其它参考4


@tasmaniski:你的回答对我有用。我有同样的问题,我建议那些一直在寻找相同答案的人。这是来自@tasmaniski:


<?php 
    $random = substr(md5(mt_rand()), 0, 7);
    echo $random;
?>

其它参考5


根据您的应用程序(我想生成密码),您可以使用


$string = base64_encode(openssl_random_pseudo_bytes(30));


作为base64,它们可能包含=-以及请求的字符。您可以生成一个更长的字符串,然后过滤并修剪它以删除它们。


openssl_random_pseudo_bytes似乎是在php中生成适当随机数的推荐方法。为什么rand不使用/dev/random我不知道。

其它参考6


我知道这可能有点晚了,但是这里有一个简单的单行程序,可以生成一个真正的随机字符串,而无需任何脚本级循环或使用openssl库。


echo substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,10))),1,10);


将其分解以使参数清晰


// Character List to Pick from
$chrList = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

// Minimum/Maximum times to repeat character List to seed from
$chrRepeatMin = 1; // Minimum times to repeat the seed string
$chrRepeatMax = 10; // Maximum times to repeat the seed string

// Length of Random String returned
$chrRandomLength = 10;

// The ONE LINE random command with the above variables.
echo substr(str_shuffle(str_repeat($chrList, mt_rand($chrRepeatMin,$chrRepeatMax))),1,$chrRandomLength);


此方法通过随机重复字符列表,然后混合组合字符串,并返回指定的字符数来工作。


您可以通过随机化返回的字符串的长度,将$chrRandomLength替换为mt_rand(8, 15)(对于8到15个字符之间的随机字符串)进一步随机化。

其它参考7


实现此功能的更好方法是:


function RandomString($length) {
    $keys = array_merge(range(0,9), range('a', 'z'));

    $key = "";
    for($i=0; $i < $length; $i++) {
        $key .= $keys[mt_rand(0, count($keys) - 1)];
    }
    return $key;
}

echo RandomString(20);


mt_rand在php7中根据这个和这个更随机。 rand函数是mt_rand的别名。[82] [83]

其它参考8


function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}


田田!

其它参考9


函数范围中的$randstring与您调用它的范围不同。您必须将返回值分配给变量。


$randstring = RandomString();
echo $randstring;


或者只是直接回显返回值:


echo RandomString();


另外,在你的功能中你有一点错误。在for循环中,您需要使用.=,以便每个字符都附加到字符串中。通过使用=,您将使用每个新字符覆盖它而不是附加。


$randstring .= $characters[rand(0, strlen($characters))];

其它参考10


首先,定义要使用的字母表:


$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$special  = '~!@#$%^&*(){}[],./?';
$alphabet = $alphanum . $special;


然后,使用openssl_random_pseudo_bytes()生成适当的随机数据:[84]


$len = 12; // length of password
$random = openssl_random_pseudo_bytes($len);


最后,您使用此随机数据来创建密码。因为$random中的每个字符都可以是chr(0)直到chr(255),所以代码使用$alphabet_length除以其序数值后的余数,以确保只挑选字母表中的字符(注意这样做会降低随机性):


$alphabet_length = strlen($alphabet);
$password = '';
for ($i = 0; $i < $len; ++$i) {
    $password .= $alphabet[ord($random[$i]) % $alphabet_length];
}


或者,通常更好,是使用RandomLib和SecurityLib:[85] [86]


use SecurityLib\Strength;

$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new Strength(Strength::MEDIUM));

$password = $generator->generateString(12, $alphabet);

其它参考11


简短方法..



以下是生成随机字符串的最简短方法


<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15); 

echo substr(md5(rand()), 0, 7);

echo str_shuffle(MD5(microtime()));
?>

其它参考12


function rndStr($len = 64) {
     $randomData = file_get_contents('/dev/urandom', false, null, 0, $len) . uniqid(mt_rand(), true);
     $str = substr(str_replace(array('/','=','+'),'', base64_encode($randomData)),0,$len);
    return $str;
}

其它参考13


这个来自顾客来源:[87]


/** Get a random string
* @return string 32 hexadecimal characters
*/
function rand_string() {
    return md5(uniqid(mt_rand(), true));
}


Adminer,用PHP编写的数据库管理工具。[88]

其它参考14


一个非常快速的方法是做一些事情:


substr(md5(rand()),0,10);


这将生成一个长度为10个字符的随机字符串。当然,有些人可能会说它在计算方面有点沉重,但现在处理器已经过优化,可以非常快速地运行md5或sha256算法。当然,如果rand()函数返回相同的值,结果将是相同的,有1/32767的机会是相同的。如果安全是问题,那么只需将rand()更改为mt_rand()

其它参考15


Laravel 5框架中的Helper功能


/**
 * Generate a "random" alpha-numeric string.
 *
 * Should not be considered sufficient for cryptography, etc.
 *
 * @param  int  $length
 * @return string
 */
function str_random($length = 16)
{
    $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}

其它参考16


我已经测试了那里最流行的功能的性能,在我的盒子上生成1000000个32个符号的字符串所需的时间是:


2.5 $s = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,32);
1.9 $s = base64_encode(openssl_random_pseudo_bytes(24));
1.68 $s = bin2hex(openssl_random_pseudo_bytes(16));
0.63 $s = base64_encode(random_bytes(24));
0.62 $s = bin2hex(random_bytes(16));
0.37 $s = substr(md5(rand()), 0, 32);
0.37 $s = substr(md5(mt_rand()), 0, 32);


请注意它确实存在多长时间并不重要但速度较慢哪一个更快,因此您可以根据您的要求进行选择,包括加密准备等。


为了准确起见,添加了MD5周围的substr(),如果你需要短于32个符号的字符串。


为了回答:字符串没有连接但是被覆盖,并且没有存储函数的结果。

其它参考17


该函数的编辑版本工作正常,只是我发现的一个问题:您使用了错误的字符来包含$字符,因此'字符有时是生成的随机字符串的一部分。


要解决此问题,请更改:


$characters = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;


至:


$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';


这样,只使用包含的字符,'字符永远不会是生成的随机字符串的一部分。

其它参考18


另一个单行,生成随机字符串,包含10个字母和数字字符。它将创建一个带range的数组(调整第二个参数来设置大小),循环遍历此数组并分配一个随机的ascii-char(范围0-9或az),然后内爆数组以获取字符串。


$str = implode('', array_map(function () { return chr(rand(0, 1) ? rand(48, 57) : rand(97, 122)); }, range(0, 9)));


注意:仅适用于PHP 5.3 +

其它参考19


一条线。
快速的巨大弦乐与一些独特性。


function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}

其它参考20


我喜欢使用openssl_random_pseudo_bytes的最后一条评论,但它不是我的解决方案,因为我仍然需要删除我不想要的字符,而且我无法获得设定长度字符串。这是我的解决方案.. 。


function rndStr($len = 20) {
    $rnd='';
    for($i=0;$i<$len;$i++) {
        do {
            $byte = openssl_random_pseudo_bytes(1);
            $asc = chr(base_convert(substr(bin2hex($byte),0,2),16,10));
        } while(!ctype_alnum($asc));
        $rnd .= $asc;
    }
    return $rnd;
}

其它参考21


function randomString($length = 5) {
       return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}

其它参考22


/**
 * @param int $length
 * @param string $abc
 * @return string
 */
function generateRandomString($length = 10, $abc = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
    return substr(str_shuffle($abc), 0, $length);
}


来自http://www.xeweb.net/2011/02/11/generate-a-random-string-a-z-0-9-in-php/[89]

其它参考23


在PHP中生成随机字符串的另一种方法是:[90]


function RandomString($length) {
    $original_string = array_merge(range(0,9), range('a','z'), range('A', 'Z'));
    $original_string = implode("", $original_string);
    return substr(str_shuffle($original_string), 0, $length);
}
echo RandomString(6);

其它参考24


有一个简单的代码:


echo implode("",array_map(create_function('$s','return substr($s,mt_rand(0,strlen($s)),1);'),array_fill(0,16,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")));


有简单的指南:



  • 要更改字符串长度,请仅将16更改为其他值。

  • 要从不同的字符中选择,请更改字符串。


其它参考25


最后,我找到了一个获得随机和独特价值的解决方案
我的解决方案是


substr(md5(time()), 0, 12)


时间总是返回timstamp,它始终是唯一的。您可以将它与md5一起使用以使其更好。

其它参考26


<?php
    /**
     * Creates a random string
     *
     * @param (int) $length
     *   Length in characters
     * @param (array) $ranges
     *   (optional) Array of ranges to be used
     *
     * @return
     * Random string
    */
    function random_string($length, $ranges = array('0-9', 'a-z', 'A-Z')) {
        foreach ($ranges as $r) $s .= implode(range(array_shift($r = explode('-', $r)), $r[1]));
        while (strlen($s) < $length) $s .= $s;
        return substr(str_shuffle($s), 0, $length);
    }

    // Examples:
    $l = 100;
    echo '<b>Default:</b> ' . random_string($l) . '<br />';
    echo '<b>Lower Case only:</b> ' . random_string($l, array('a-z')) . '<br />';
    echo '<b>HEX only:</b> ' . random_string($l, array('0-9', 'A-F')) . '<br />';
    echo '<b>BIN only:</b> ' . random_string($l, array('0-1')) . '<br />';

/* End of file */

其它参考27


function getRandomString($length) {
  $salt = array_merge(range('a', 'z'), range(0, 9));
  $maxIndex = count($salt) - 1;

  $result = '';
  for ($i = 0; $i < $length; $i++) {
    $index = mt_rand(0, $maxIndex);
    $result .= $salt[$index];
  }
  return $result
}

其它参考28


以下是我如何获取真正的唯一随机密钥:


$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;


你可以使用time(),因为它是一个Unix时间戳,并且与上面提到的其他随机数相比总是唯一的。然后,您可以生成md5sum,并从生成的MD5字符串中获取所需的长度。在这种情况下,我使用10个字符,如果我想让它更独特,我可以使用更长的字符串。[91]


我希望这有帮助。

其它参考29


来源:生成随机字符的PHP函数[92]


这个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);