生成(伪)随机字母数字字符串

87

我该如何在PHP中生成一个(伪)随机的字母数字字符串,例如:“d79jd8c”?


解决方案简短而独特。 请参考此链接https://dev59.com/52Mk5IYBdhLWcg3wvARo#34467730 - Saud Khan
方法 Random::alphanumericString($length) 可以实现你想要的功能。如果你想自己构建,请不要使用除 PHP 内置的 random_bytesrandom_int 之外的任何随机源。 - caw
18个回答

166
首先,使用所有可能的字符创建一个字符串:
 $characters = 'abcdefghijklmnopqrstuvwxyz0123456789';

您还可以使用range()更快地完成此操作。

然后,在循环中,选择一个随机数字,并将其用作索引来获取随机字符的$characters字符串,并将其附加到您的字符串中:

 $string = '';
 $max = strlen($characters) - 1;
 for ($i = 0; $i < $random_string_length; $i++) {
      $string .= $characters[mt_rand(0, $max)];
 }

$random_string_length是随机字符串的长度。


9
如果您想删除看起来相同的字符,例如“l”和“1”、“O”和“0”,那么这种实现也很好。当为用户生成新密码时,这是值得做的。 - Mark Nold
10
我也使用这种技巧,删除所有元音字母,这样我就不会因为密码中含有不当内容而给别人带来困扰。 - nickf
10
小改进:mt_rand()rand()的替代品,且更好。 - Grilse
11
每次循环执行strlen()并不好。将strlen($characters) - 1赋值给一个变量,在循环外执行strlen。虽然在这种情况下不是必要的,但这只是一种Mauvais ton - mintobit
6
如果您需要加密安全的随机数,请考虑使用random_int - reallynice
显示剩余3条评论

18

我喜欢这个函数来完成这项工作

function randomKey($length) {
    $pool = array_merge(range(0,9), range('a', 'z'),range('A', 'Z'));

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

echo randomKey(20);

14

使用openssl_random_pseudo_bytes函数生成8字符长的加密强度随机字符串:

echo bin2hex(openssl_random_pseudo_bytes(4));

流程化方法:

function randomString(int $length): string
{
    return bin2hex(openssl_random_pseudo_bytes($length));
}

更新:

PHP7引入了random_x()函数,应该会更好。如果你来自PHP 5.X,请使用出色的paragonie/random_compat库,它是PHP 7的random_bytes()random_int()的填充程序。

function randomString($length)
{
    return bin2hex(random_bytes($length));
}

9

一行代码解决方案:

echo substr( str_shuffle( str_repeat( 'abcdefghijklmnopqrstuvwxyz0123456789', 10 ) ), 0, 7 );

您可以更改substr参数以设置字符串的不同长度。

4

我知道这是一篇老文章,但我想分享一个类,它基于Jeremy Ruten的答案并结合评论中的建议得到了改进:

    class RandomString
    {
      private static $characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
      private static $string;
      private static $length = 8; //default random string length

      public static function generate($length = null)
      {

        if($length){
          self::$length = $length;
        }

        $characters_length = strlen(self::$characters) - 1;

        for ($i = 0; $i < self::$length; $i++) {
          self::$string .= self::$characters[mt_rand(0, $characters_length)];
        }

        return self::$string;

      }

    }

4
使用ASCII表选择字母范围,其中:$range_start,$range_end是ASCII表中十进制列中的值。
我发现这种方法比另一种方法更好,后者在另一个字符串中特别定义了字符范围。
// range is numbers (48) through capital and lower case letters (122)
$range_start = 48;
$range_end   = 122;
$random_string = "";
$random_string_length = 10;

for ($i = 0; $i < $random_string_length; $i++) {
  $ascii_no = round( mt_rand( $range_start , $range_end ) ); // generates a number within the range
  // finds the character represented by $ascii_no and adds it to the random string
  // study **chr** function for a better understanding
  $random_string .= chr( $ascii_no );
}

echo $random_string;

查看更多:


1
这很好,尽管非字母数字字符落在ACSII范围内。 - Bower

4
简单来说,每个字节都是0到255之间的随机数,对于一个随机字符串来说这样就很好了。还要记住你需要用两个字符来表示每个字节。
$str = bin2hex(random_bytes(32));  // 64 character string returned

到目前为止最好的答案和最短的代码!这应该得到更多的赞。 - Sliq

2
我制作了以下快速函数,只是为了玩弄range()函数。它可能会在某个时候帮助到某个人。
Function pseudostring($length = 50) {

    // Generate arrays with characters and numbers
    $lowerAlpha = range('a', 'z');
    $upperAlpha = range('A', 'Z');
    $numeric = range('0', '9');

    // Merge the arrays
    $workArray = array_merge($numeric, array_merge($lowerAlpha, $upperAlpha));
    $returnString = "";

    // Add random characters from the created array to a string
    for ($i = 0; $i < $length; $i++) {
        $character = $workArray[rand(0, 61)];
        $returnString .= $character;
    }

    return $returnString;
}

2
也许我在这里漏掉了什么,但是可以使用uniqid()函数 (详细说明)

2
uniqid在任何情况下都不是随机的。它是完全可预测的。这个问题非常明确地寻找伪随机字符串。 - user229044

2
您可以使用以下代码。它类似于现有函数,不同之处在于您可以强制特殊字符计数:
function random_string() {
    // 8 characters: 7 lower-case alphabets and 1 digit
    $character_sets = [
        ["count" => 7, "characters" => "abcdefghijklmnopqrstuvwxyz"],
        ["count" => 1, "characters" => "0123456789"]
    ];
    $temp_array = array();
    foreach ($character_sets as $character_set) {
        for ($i = 0; $i < $character_set["count"]; $i++) {
            $random = random_int(0, strlen($character_set["characters"]) - 1);
            $temp_array[] = $character_set["characters"][$random];
        }
    }
    shuffle($temp_array);
    return implode("", $temp_array);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接