如何使用 PHP 创建随机字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/853813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:06:03  来源:igfitidea点击:

How to create a random string using PHP?

phpstringrandom

提问by Keith Donegan

I know that the rand function in PHP generates random integers, but what is the best way to generate a random string such as:

我知道 PHP 中的 rand 函数会生成随机整数,但是生成随机字符串的最佳方法是什么,例如:

Original string, 9 chars

原始字符串,9 个字符

$string = 'abcdefghi';

Example random string limiting to 6 chars

示例随机字符串限制为 6 个字符

$string = 'ibfeca';

UPDATE: I have found tons of these types of functions, basically I'm trying to understand the logic behind each step.

更新:我发现了大量这些类型的函数,基本上我试图理解每一步背后的逻辑。

UPDATE: The function should generate any amount of chars as required.

更新:该函数应根据需要生成任意数量的字符。

Please comment the parts if you reply.

如果您回复,请评论部分。

回答by Gumbo

If you want to allow repetitive occurences of characters, you can use this function:

如果你想允许字符重复出现,你可以使用这个函数:

function randString($length, $charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
{
    $str = '';
    $count = strlen($charset);
    while ($length--) {
        $str .= $charset[mt_rand(0, $count-1)];
    }
    return $str;
}

The basic algorithm is to generate <length> times a random number between 0 and <number of characters> ? 1 we use as index to pick a character from our set and concatenate those characters. The 0 and <number of characters> ? 1 bounds represent the bounds of the $charsetstring as the first character is addressed with $charset[0]and the last with $charset[count($charset) - 1].

基本算法是生成<长度>乘以0到<字符数>之间的随机数?1 我们用作索引从我们的集合中选择一个字符并连接这些字符。0 和 <字符数> ? 1 边界表示$charset字符串的边界,因为第一个字符用 寻址,$charset[0]最后一个字符用 寻址$charset[count($charset) - 1]

回答by Chad Birch

Well, you didn't clarify all the questions I asked in my comment, but I'll assume that you want a function that can take a string of "possible" characters and a length of string to return. Commented thoroughly as requested, using more variables than I would normally, for clarity:

好吧,你没有澄清我在评论中提出的所有问题,但我假设你想要一个函数,它可以接受一串“可能”的字符和一段字符串返回。为清楚起见,按照要求进行了彻底评论,使用了比我平时更多的变量:

function get_random_string($valid_chars, $length)
{
    // start with an empty random string
    $random_string = "";

    // count the number of chars in the valid chars string so we know how many choices we have
    $num_valid_chars = strlen($valid_chars);

    // repeat the steps until we've created a string of the right length
    for ($i = 0; $i < $length; $i++)
    {
        // pick a random number from 1 up to the number of valid chars
        $random_pick = mt_rand(1, $num_valid_chars);

        // take the random character out of the string of valid chars
        // subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
        $random_char = $valid_chars[$random_pick-1];

        // add the randomly-chosen char onto the end of our string so far
        $random_string .= $random_char;
    }

    // return our finished random string
    return $random_string;
}

To call this function with your example data, you'd call it something like:

要使用您的示例数据调用此函数,您可以将其命名为:

$original_string = 'abcdefghi';
$random_string = get_random_string($original_string, 6);

Note that this function doesn't check for uniqueness in the valid chars passed to it. For example, if you called it with a valid chars string of 'AAAB', it would be three times more likely to choose an A for each letter as a B. That could be considered a bug or a feature, depending on your needs.

请注意,此函数不会检查传递给它的有效字符的唯一性。例如,如果您使用有效字符字符串 调用它,'AAAB'则为每个字母选择 A 作为 B 的可能性要高出三倍。这可能被视为错误或功能,具体取决于您的需要。

回答by tasmaniski

My favorite:

我最喜欢的:

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

回答by ircmaxell

So, let me start off by saying USE A LIBRARY. Many exist:

所以,让我先说USE A LIBRARY。许多存在:

The core of the problem is almost every answer in this page is susceptible to attack. mt_rand(), rand(), lcg_value()and uniqid()are all vulnerable to attack.

问题的核心是几乎这个页面中的每个答案都容易受到攻击。mt_rand(), rand(),lcg_value()uniqid()容易受到攻击

A good system will use /dev/urandomfrom the filesystem, or mcrypt_create_iv()(with MCRYPT_DEV_URANDOM) or openssl_pseudo_random_bytes(). Which all of the above do. PHP 7 will come with two new functionsrandom_bytes($len)and random_int($min, $max)that are also safe.

一个好的系统将使用/dev/urandom来自文件系统,或mcrypt_create_iv()(与MCRYPT_DEV_URANDOM)或openssl_pseudo_random_bytes(). 以上都是这样做的。PHP 7将带着两个新的功能random_bytes($len)random_int($min, $max)那也是安全的。

Be aware that most of those functions (except random_int()) return "raw strings" meaning they can contain any ASCII character from 0 - 255. If you want a printable string, I'd suggest running the result through base64_encode().

请注意,大多数这些函数(除了random_int())返回“原始字符串”,这意味着它们可以包含来自0 - 255. 如果你想要一个可打印的字符串,我建议通过base64_encode().

回答by ircmaxell

function generate_random_string($name_length = 8) {
    $alpha_numeric = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    return substr(str_shuffle(str_repeat($alpha_numeric, $name_length)), 0, $name_length);
}

Updated the code as per mzhang's great suggestion in the comments below.

根据mzhang在下面评论中的伟大建议更新了代码。

回答by Sliq

A better and updated version of @taskamiski's excellent answer:

@taskamiski 的优秀答案的更好和更新版本:

Better version, using mt_rand()instead of rand():

更好的版本,使用mt_rand()代替rand()

echo md5(mt_rand()); // 32 char string = 128bit

Even better, for longer strings, using the hash()function that allows to select hashing algorithmns:

更好的是,对于更长的字符串,使用hash()允许选择散列算法的函数:

echo hash('sha256', mt_rand()); // 64 char string
echo hash('sha512', mt_rand()); // 128 char string

If you want to cut the result down to let's say 50 chars, do it like this:

如果您想将结果减少到 50 个字符,请这样做:

echo substr(hash('sha256', mt_rand()), 0, 50); // 50 char string

回答by Imran

Joining characters at the end should be more efficient that repeated string concatenation.

最后加入字符应该比重复字符串连接更有效。

Edit #1: Added option to avoid character repetition.

编辑 #1:添加了避免字符重复的选项。

Edit #2: Throws exception to avoid getting into infinite loop if $norepeat is selected and $len is greater than the charset to pick from.

编辑 #2:如果选择了 $norepeat 并且 $len 大于要从中选择的字符集,则抛出异常以避免进入无限循环。

Edit #3: Uses array keys to store picked random characters when $norepeat is selected, as associative array key lookup is faster than linearly searching the array.

编辑#3:使用数组键在选择$ norepeat时存储挑选的随机字符,因为关联数组密钥查找速度比线性搜索阵列更快。

function rand_str($len, $norepeat = true)
{
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $max = strlen($chars) - 1;

    if ($norepeat && len > $max + 1) {
        throw new Exception("Non repetitive random string can't be longer than charset");
    }

    $rand_chars = array();

    while ($len) {
        $picked = $chars[mt_rand(0, $max)];

        if ($norepeat) {
            if (!array_key_exists($picked, $rand_chars)) {
                $rand_chars[$picked] = true;
                $len--;
            }
        }
        else {
            $rand_chars[] = $picked;
            $len--;
        }
    }

    return implode('', $norepeat ? array_keys($rand_chars) : $rand_chars);   
}

回答by Akhilraj N S

this will generate random string

这将生成随机字符串

function generateRandomString($length=10) {
    $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 generateRandomString(6);

回答by zeeks

I think I will add my contribution here as well.

我想我也会在这里添加我的贡献。

function random_string($length) {
    $bytes_1 = openssl_random_pseudo_bytes($length);
    $hex_1 = bin2hex($bytes_1);
    $random_numbers = substr(sha1(rand()), 0, $length);
    $bytes_2 = openssl_random_pseudo_bytes($length);
    $hex_2 = bin2hex($bytes_2);
    $combined_chars = $hex_1 . $random_numbers . $hex_2;
    $chars_crypted = hash('sha512', $combined_chars);

    return $chars_crypted;
}

Thanks

谢谢

回答by Scott Arciszewski

What do you need a random string for?

你需要一个随机字符串做什么?

Is this going to be used for anything remotely analogous to a password?

这将用于远程类似于密码的任何东西吗?

If your random string requires anysecurity properties at all, you should use PHP 7's random_int()function instead of all the insecure mt_rand()answers in this thread.

如果您的随机字符串根本需要任何安全属性,您应该使用 PHP 7 的random_int()函数而不是mt_rand()该线程中的所有不安全答案。

/**
 * Generate a random string
 * 
 * @link https://paragonie.com/b/JvICXzh_jhLyt4y3
 *
 * @param int $length - How long should our random string be?
 * @param string $charset - A string of all possible characters to choose from
 * @return string
 */
function random_str($length = 32, $charset = 'abcdefghijklmnopqrstuvwxyz')
{
    // Type checks:
    if (!is_numeric($length)) {
        throw new InvalidArgumentException(
            'random_str - Argument 1 - expected an integer'
        );
    }
    if (!is_string($charset)) {
        throw new InvalidArgumentException(
            'random_str - Argument 2 - expected a string'
        );
    }

    if ($length < 1) {
        // Just return an empty string. Any value < 1 is meaningless.
        return '';
    }
    // This is the maximum index for all of the characters in the string $charset
    $charset_max = strlen($charset) - 1;
    if ($charset_max < 1) {
        // Avoid letting users do: random_str($int, 'a'); -> 'aaaaa...'
        throw new LogicException(
            'random_str - Argument 2 - expected a string at least 2 characters long'
        );
    }
    // Now that we have good data, this is the meat of our function:
    $random_str = '';
    for ($i = 0; $i < $length; ++$i) {
        $r = random_int(0, $charset_max);
        $random_str .= $charset[$r];
    }
    return $random_str;
}

If you aren't on PHP 7 yet (which is probably the case, as it hasn't been released as of this writing), then you'll want paragonie/random_compat, which is a userland implementation of random_bytes()and random_int()for PHP 5 projects.

如果您还没有使用 PHP 7(可能是这种情况,因为在撰写本文时它还没有发布),那么您将需要paragonie/random_compat,它是PHP 5 项目的用户空间实现random_bytes()random_int()用于 PHP 5 项目。

For security contexts, alwaysuse random_int(), not rand(), mt_rand(), etc.See ircmaxell's answeras well.

出于安全环境中,总是使用random_int(),不rand()mt_rand()ircmaxell的回答也是如此。